Replace every symbol at once, then read the result as line segments — step, turn, and branch.
Rewriting, then walking
An L-system has two halves that know nothing about each other.
The first is string rewriting. Start from an axiom, and in each generation replace
every symbol simultaneously by its production:
axiom: F--F--F
rule: F → F+F--F+F (Koch, at 60°)
Simultaneity is the whole idea, and it is what separates an L-system from a formal
grammar: a grammar rewrites one symbol at a time, an L-system rewrites all of them at
once. Aristid Lindenmayer introduced them in 1968 to model how plant cells divide —
every cell dividing in the same time step, not in sequence.
The second half is an interpreter that reads the resulting word as placed
line segments:
| Symbol | Action |
|---|
F A B | draw forward one unit |
+ | turn left by the angle |
− | turn right by the angle |
[ | push position and heading |
] | pop them |
Anything else is ignored. The interpreter has no idea what a snowflake is.
The first rewrite. At this length the word could still be read aloud.
The second. The word has grown by a factor of four per generation — each F becomes four
Fs — and the figure has gained a corresponding level of detail.
Self-similarity comes free
The third rewrite. Nothing in the system describes self-similarity — it is a consequence
of applying one rule to its own output. Each F in generation n becomes the whole
generation-1 figure in generation n+1, at a third of the scale, which is exactly the
statement that the figure contains copies of itself.
The axiom is F--F--F: three sides with -- between them, which at 60° is a 120°
turn — an equilateral triangle. Every side then grows the Koch bump, and the snowflake
is what results.
Brackets are the difference between a curve and a plant
The [ and ] symbols branch the placement:
case '[': branches.Push(placement); break;
case ']': placement = branches.Pop(); break;
Without them a word describes a single connected path, and the only figures possible
are curves — Koch, Sierpiński arrowhead, dragon. With them the path can go down a
branch and return, and the figure becomes a tree.
Three renderings use them — Plant, Binary Tree, and Bush — and the curves do
not. That one pair of symbols is the entire difference between the two families.
The fourth.
The last rewrite the preset asks for — five, for the snowflake. The ten renderings do
not stop at the same depth, because their rules grow at very different rates: the
Gosper curve stops at four, the arrowhead at eight, the dragon and the Lévy curve at
thirteen.
Refitting
Every stage measures the figure’s bounding box and scales it to the frame:
// The figure's extent: min and max over every segment endpoint.
The segments are collected before anything is drawn, precisely so the extent is known
in advance. That matters because an L-system figure does not keep its shape between
generations — the Koch snowflake’s bounding box grows and the plant’s leans further
with each rewrite — so a fixed scale would push later stages off the canvas.
The visible consequence is that the unit step shrinks as the progression runs. The
figure stays the same size on the page; the segments it is made of do not.
Ten systems
| Rendering | Axiom | Rules | Angle | Iterations |
|---|
| Koch Snowflake | F--F--F | F → F+F--F+F | 60° | 5 |
| Dragon Curve | A | A → A+B+, B → -A-B | 90° | 13 |
| Hilbert Curve | A | A → +BF-AFA-FB+, B → -AF+BFB+FA- | 90° | 6 |
| Gosper Curve | A | A → A-B--B+A++AA+B-, B → +A-BB--B-A++A+B | 60° | 4 |
| Lévy Curve | F | F → +F--F+ | 45° | 13 |
| Sierpinski Arrow | A | A → B-A-B, B → A+B+A | 60° | 8 |
| Plant | X | X → F+[[X]-X]-F[-FX]+X, F → FF | 25° | 6 |
| Binary Tree | X | X → F[+X][-X]FX, F → FF | 25.7° | 6 |
| Bush | X | X → F-[[X]+X]+F[+FX]-X, F → FF | 22.5° | 6 |
| Crystal | F--F--F | F → F+F--F+F (drawn twice, nested) | 60° | 5 |
Four of them are worth reading twice: the dragon, the Hilbert curve, the Gosper curve,
and the arrowhead are each written with two drawing symbols, A and B, whose
productions refer to each other. Neither rule is self-similar on its own; the pair is.
The arrowhead’s limit figure is the Sierpiński triangle drawn as a single unbroken
path; the Gosper curve’s is an island whose outline is the regular hexagon; the
Hilbert curve’s is the whole square, visited in a single unbroken path.
The Crystal is the snowflake’s sentence drawn a second time over itself — half the
size, rotated 15°, recolored gold. The interpreter that walks a sentence can also be
asked to walk it again at a new scale, which is layering without any new grammar.
The museum plate
The gallery closes with the lead presented as a finished piece: the snowflake hung
on a lit wall behind a mat and a dark frame. The frame is a separate layer —
MuseumFrame — that owns no generative state and knows nothing about L-systems;
it contain-fits any artwork into the mat opening and hangs it as the closing
plate. It is presentation, not rewriting, so it appears once, as the finished
plate, rather than as a framed copy of every variant.
Determinism
Nothing is seeded and nothing is random. Rewriting is string substitution and the
interpretation is trigonometry on the accumulated rotation. The museum plate is the
same discipline in a different medium: fixed colours, fixed geometry, and a drop
shadow whose strength and spread are fixed fractions of the canvas.