2D Origami Simulator
How it Works
Motivation
Who would want a paper simulator online when there are probably several sheets of the real thing right next to you, right?
This was not intended to be an alternative to real-life folding, nor is it meant as an experimentation tool (it doesn't even save on CO2 emissions [1]). Rather I would like it to be a precursor to a more advanced, 3D version in which fold sequences can be animated to make instructional or artistic videos. I could not find any evidence online of previous attempts to make this, but did rediscover an old puzzle-game favourite of mine: Bryce Summer's 'Folds.' It wasn't immediatly obvious to me how the game worked, so I tried to recreate its mechanics as closely as possible in an effort to find out. I think I was successful.
Modelling a Fold
While the action of folding a piece of paper is a simple thing to describe in the physical world, simulating it with code is a little trickier. The method used here is to divide the original sheet along the new crease into two piece, each a polygon defined by its vertex points, then reflecting the vertices of one piece along the crease. If the sheet has already been folded then it will consist of multiple polygons, each of which is split if it intersects the fold line.
The crease is defined with two points that are found with simple euclidean geometry. The coordinates of the initial mouse click are saved as (x1,y1)
, while the current mouse position (x2,y2)
is redefined on each subsequent movement. The two points used to define the fold line are
( (x1+x2)/2 , (y1+y2)/2 )
( (x1+x2+y1+y2)/2 – y1 , (y1+y2–x1–x2)/2 + x1 )
Both are equidistant to (x1,y1)
and (x2,y2)
. Once the mouse is released, a fold is made along this line.
It is important to note that the polygons created will always be convex and therefore intersect the fold line at most twice. A polygon intersecting fewer than two times is left unchanged, otherwise the line divides the vertices between two new polygons and the intersection points are added to each.
In deciding which vertices to reflect and which to leave in place we need a quick way of checking whether or not a vertex is on the same side of the fold line as the initial mouse click. We can deduce that a point (x,y)
is on the same side of the line as (x1,y1)
if and only if the folowing equation holds:
((py–qy)(x–px) + (qx–px)(y–py)) × ((py–qy)(x1–px) + (qx–px)(x2–py)) > 0
Where (px,py)
and (qx,qy)
are the two known points on the fold line.
Undo and Redo
Every time a fold is completed, the current state of polygons and their nodes is saved as the last in an array of all past states. These can then be navigated through with the <
and >
buttons. During navigation there can be both past and future states existing in the array, but any future states are deleted if a new fold is made. All memory of past or future states is cleared when the "Reset" button is pushed.
A major drawback of Javascript in this type of operation is its inability to easily make deep clones. In other words, a command like pastStates.push(currentState)
will only create new references to the many objects contained in currentState
and so will not remain constant as the current state is changed. Otherwise elegant, via-JSON solutions fail due to some objects containing functions as well as variables. In the end, such copies were constructed manually, creating new, empty objects at each level and copying the non-object variables across one-by-one.
Zooming In/Out
The zoom in/out functionality is minimally complicated. The zoom does not affect any of the core functions – it is only known by the mouse locator and polygon drawing functions. The section of the full picture currently being shown is stored as the x,y-coordinates of the upper-left corner along with the side length. Each mouse click is mapped to its coordinates in the fully zoomed-out picture and the inverse function is used to plot the points of each fold vertex while drawing. To avoid confusion, the zoom out button escapes all layers of magnification and returns the view to the full-sized starting point.
Length of Code
The simulator runs on under 250 lines of functional Javascript, and the page has no more than 40 lines of HTML or 20 lines of CSS. The current Javascript file is suspected to have unnecessary variables. Efforts are currently being made to clean these up and streamline the core functions.
[1] Approx. 100g of CO2 equivalents to produce 20 sheets of office paper – CO2List.org, Two Sides Facts; 106g to load 15KB webpage – A List Apart.