Skip to content

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 .y

The 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 .d
.b .c .a .d axiom 1 · through
Axiom 1 — lines through pairs of corners

4.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 .y

The 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 --c2

The 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 .center
.b .c .a .d --d1 --d2 axiom 1 · through axiom 2 · map onto
Construction — intersection yields the midpoint

4.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 .p

The 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 .b
.a .b .c .d --diag axiom 3 · perp axiom 1 · through
Axiom 3 — perpendicular through a point

4.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 .p

The 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 --r
.b .c .a .d axiom 5 · map onto
Axiom 5 — bisector of parallel lines (midline)

4.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 --l2

The 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 O7not 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 .c
.b .d .a .c --vmid --hmid --l1 --l2 axiom 4 · project axiom 2 · map onto axiom 1 · through
.b .d .a --vmid --hmid --l1 --l2 axiom 4 · project axiom 2 · map onto axiom 1 · through
Axiom 4 — project a point onto a line

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 .p picks the side that moves — the flap containing material point .p. For @map .x onto .y it defaults to .x (the moved point); the line-construction folds (@through, @perp, @map --l onto --m) have no natural default and require moving.
  • mountain sets 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 .b
.a .d .b .c axiom 2 · map onto
.a .d .a .d axiom 2 · map onto
Folding — @ folds the paper in half

4.7 flip — turn the sheet over (since v0.7-dev)

Section titled “4.7 flip — turn the sheet over (since v0.7-dev)”
flip

Turns 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
.b .c .a .d axiom 2 · map onto
.a .d .a .d axiom 2 · map onto
flip — turn the sheet over, then fold