Operations
4. Operations
Section titled “4. Operations”4.1 Axiom 1 — line through two points (since v0.0)
Section titled “4.1 Axiom 1 — line through two points (since v0.0)”through .x .yThe unique fold line passing through points .x and .y
[justin1986], [hull2020] §1.5 (O1).
Error if .x and .y are the same point (no unique line).
; status: works — both diagonals of the square
paper square
through .a .c
through .b .d4.2 Axiom 2 — fold one point onto another (since v0.0)
Section titled “4.2 Axiom 2 — fold one point onto another (since v0.0)”map .x onto .yThe fold that places .x onto .y: the perpendicular bisector of the segment
x–y [justin1986],
[hull2020] §1.5 (O3 in Hull’s numbering; see §1).
Error if .x and .y are the same point.
(since v0.6-dev: verb is map … onto …; was fold … to ….)
4.3 Construction — intersection of two creases (since v0.0)
Section titled “4.3 Construction — intersection of two creases (since v0.0)”cross --c1 --c2The point where the two creases’ lines meet. This is a point construction, not a fold axiom, in the classic numbering; it is Hull’s basic operation O2 [hull2020] §1.5 (O2).
(since v0.7-dev) The intersection is a table-space point; it resolves to the
material point on the topmost layer covering that spot (Q2-B). On the flat,
unfolded sheet there is exactly one layer, so this is just the point itself;
after folding, where several layers overlap, the visible top layer is taken —
the one your hand would touch. Errors:
- the two lines are parallel (no intersection);
- the intersection point is off the paper — no layer covers it (exact point-in-polygon test; the boundary counts as on the paper).
; status: works — two diagonals, name their crossing, map a corner onto it
paper square
--d1: through .a .c
--d2: through .b .d
.center: cross --d1 --d2
map .a onto .center4.4 Axiom 3 — perpendicular through a point (since v0.2)
Section titled “4.4 Axiom 3 — perpendicular through a point (since v0.2)”perp --l through .pThe fold line through point .p, perpendicular to crease --l
[justin1986] §8.1 (operation ③), [hull2020]
§1.5 (O5 in Hull’s numbering; see §1). This is the first axiom taking a crease
as an operand.
On the number of solutions. Operation ③ admits two fold lines exactly when
.p lies on --l: the perpendicular through .p, and --l itself (a
reflection maps a line onto itself either across a perpendicular or across the
line itself; both pass through .p only when .p ∈ --l). The second is the
trivial, identity-like solution — re-creasing the existing line, producing no
new geometry. Beloch always returns the perpendicular: it is unique and is
the meaningful construction. We deliberately ignore the trivial solution,
assuming the program wants the meaningful variant. Consequently perp has no
geometric precondition and never errors (beyond undefined-name errors).
; status: works — perpendicular from a corner onto a diagonal
paper square
--diag: through .a .c
perp --diag through .b4.5 Axiom 5 — fold one line onto another (since v0.3-dev)
Section titled “4.5 Axiom 5 — fold one line onto another (since v0.3-dev)”map --l1 onto --l2 toward .pThe fold placing line --l1 onto line --l2: the angle bisector
[justin1986] §8.1 (operation ⑤), [hull2020]
§1.5 (O4 in Hull’s numbering; see §1). Two intersecting lines have two
bisectors (perpendicular to each other); the optional toward .p selector picks
the one whose angular sector contains .p. Two parallel lines have a single
midline, and toward is ignored.
Errors: the two lines are the same line; the lines intersect and
toward is omitted (ambiguous); .p lies on --l1 or --l2
(ambiguous).
This is the first axiom whose result leaves ℚ — the bisector of two rational
lines is generally irrational (slope √2−1 for y=0 and y=x). All geometry is
now computed over exact constructible reals (Num; see
ADR 0010 and §6), so equality,
parallelism, and on-paper tests stay exact.
(since v0.6-dev: verb is map … onto …; was bisect ….)
; status: works — mapping two parallel edges onto each other yields their midline (no toward)
paper square
--l: through .a .d ; left edge x = 0
--r: through .b .c ; right edge x = 1
map --l onto --r4.5a Axiom 4 — project a point onto a line (since v0.4-dev)
Section titled “4.5a Axiom 4 — project a point onto a line (since v0.4-dev)”map .p onto --l1 perp --l2The fold that places point .p onto line --l1 with a crease perpendicular
to --l2. Equivalently, .p is moved parallel to --l2 until it lands on
--l1 — the projection of .p onto --l1 parallel to --l2
[justin1986] §8.1 (operation ④). At most one solution, so
there is no toward selector.
Numbering. This is classic Justin axiom 4, which is Wikipedia’s
Huzita-Hatori O7 — not Wikipedia’s O4 (that is Beloch’s axiom 3,
perpendicular-through-a-point). See §1 and antipatterns.md.
Errors: --l1 and --l2 are parallel — no fold exists (zero solutions;
or, when .p lies on --l1, infinitely many — forbidden either way). When .p
already lies on --l1 and the lines are not parallel, the crease is the
perpendicular to --l2 through .p (one solution).
The result stays in ℚ — no square roots [justin1986] §8.2(a).
; status: works — axiom 4: project a corner onto a slanted line, crease ⊥ another line
; .c is folded onto --l1 moving along the direction of --l2; the crease ends up
; perpendicular to --l2. Render folded (`fold2svg --folded`) to watch the corner
; land on --l1; render the crease pattern to see the crease sit perpendicular to --l2.
paper square
; scaffold: two midlines give the non-corner points .tm and .rm
--vmid: map .a onto .b ; x = 1/2
--hmid: map .a onto .d ; y = 1/2
.tm: cross --vmid --(.d .c) ; midpoint of the top edge, (1/2, 1)
.rm: cross --hmid --(.b .c) ; midpoint of the right edge, (1, 1/2)
; two generic slanted lines — slopes 1/2 and 2, neither a diagonal
--l1: through .a .rm ; the line .c lands on
--l2: through .a .tm ; the crease is forced perpendicular to this
; fold corner .c onto --l1, crease perpendicular to --l2
@map .c onto --l1 perp --l2 moving .c4.6 Folding: @ (since v0.7-dev)
Section titled “4.6 Folding: @ (since v0.7-dev)”A bare axiom is a precrease: it computes a crease line and marks it; the
paper stays flat. Prefixing it with @ performs the fold:
@map .a onto .c moving .a ; fold the flap containing .a, valley@map .a onto .c moving .a mountain ; ... as a mountain@perp --l through .p moving .q ; line-construction folds need `moving`moving .ppicks the side that moves — the flap containing material point.p. For@map .x onto .yit defaults to.x(the moved point); the line-construction folds (@through,@perp,@map --l onto --m) have no natural default and requiremoving.mountainsets the fold direction; the default is valley (toward the viewer). Mountain/valley is not annotated — it is derived (see below).
Folded state. The paper is a stack of flat faces — each a convex polygon
in paper coordinates plus a rigid isometry placing it on the table — ordered
bottom→top (the layer stack). A flat fold (±180°) keeps everything in the table
plane, so the only “depth” is this stacking order. A simple fold reflects every
layer on the moving side of the crease line across it (an exact reflection — no
sqrt) and restacks: the moved flap, reversed, goes on top (valley) or
underneath (mountain). “Fold through all layers” is automatic.
Derived mountain/valley. Each crease’s assignment is
valley XOR (the cutting face is back-up), fixed when the fold runs. Because
stacked layers alternate front/back, one fold through a stack yields the correct
alternating M/V across layers (the accordion). Earlier creases keep their
assignment (material facts).
; status: works — fold the right half onto the left (valley), one crease
paper square
@map .b onto .a moving .b4.7 flip — turn the sheet over (since v0.7-dev)
Section titled “4.7 flip — turn the sheet over (since v0.7-dev)”flipTurns the whole sheet over: every face’s orientation inverts and the layer stack
reverses (so the previously bottom layer becomes reachable on top). Because
orientation inverts, a subsequent valley command is derived as a mountain
relative to the original front — i.e. “mountain = turn over, then valley.” flip
takes no axis: with named points, where the sheet lands is irrelevant, so the
reflection uses an internal canonical axis (the footprint’s vertical centerline).
A direction argument may be added later when the animation renderer needs it.
; status: works — turn the blank sheet over, then a valley command folds a mountain
paper square
flip
@map .a onto .b moving .a