L-Systems and Procedural Growth

A forest artist has a problem of scale: a single hero tree can be sculpted by hand, but a wood of ten thousand ferns, saplings and grasses cannot. Modelling each blade individually would take a lifetime, and if every plant looked identical the eye would instantly cry "copy-paste". What we want is a tiny recipe that, run over and over, grows an endless variety of believable plants — and, better still, one we can play forwards so a seedling visibly sprouts into a bush on screen.

That recipe is an L-system. Invented in 1968 by the Hungarian biologist Aristid Lindenmayer to model how algae and simple plants divide, it is one of the most beautiful ideas in procedural graphics: a handful of text-rewriting rules that, iterated, produce the branching, self-similar structure of living things. This page builds the machine from the string up, teaches the turtle that turns strings into drawings, and shows how to make a plant grow over time.

It belongs to the procedural-generation strand of the Computer Animation course, alongside its siblings noise and fractal terrain and particle systems.

The machine: alphabet, axiom, rules

An L-system rewrites strings of symbols. It has three parts, and that is genuinely all of it.

One iteration means: scan the current string and replace every symbol at once by the right-hand side of its rule (a symbol with no rule stands still). Do it again on the result, and again. Because the same rules fire everywhere simultaneously, the same little motif reappears at every scale — that is exactly the self-similarity of a branch that looks like the whole tree.

The crucial twist: rewriting is parallel

This is what separates an L-system from an ordinary grammar. A normal (Chomsky) grammar rewrites one symbol per step, chosen sequentially. An L-system rewrites all of them in the same step — the way every cell of a growing organism divides at once, not one after another down a queue. Get this wrong and every string you compute afterwards is wrong, so let us watch it on the tiniest possible example.

Alphabet \{A, B\}, axiom A, rules A \to AB and B \to A. Applying both rules to every symbol each generation:

axiom : A step 1: AB (A -> AB) step 2: ABA (A -> AB, B -> A) step 3: ABAAB (A -> AB, B -> A, A -> AB)

Read step 2 carefully: the A becomes AB and the B becomes A, both in the one step, so AB \to (AB)(A) = ABA. Now the punchline — the string lengths are

1,\; 2,\; 3,\; 5,\; 8,\; 13,\; \dots

the Fibonacci sequence. It has to be: an A produces one A and one B, and a B produces one A, so the count of A's in the next generation is the total count in this one — the very recurrence f_{n+1} = f_n + f_{n-1}. A three-line rewrite rule quietly re-derives Fibonacci. That is the flavour of an L-system: trivial local rules, rich global structure.

From strings to plants: the turtle

A string of letters is not yet a picture. To draw it we hand the finished string to a turtle — an imaginary pen with a position and a heading that reads the symbols left to right as movement commands. The classic vocabulary:

SymbolTurtle command
Fstep forward, drawing a segment
+turn left by a fixed angle
-turn right by a fixed angle
[push — save position and heading on a stack
]pop — restore the last saved position and heading

The bracket pair is the magic that makes branches. When the turtle hits [ it remembers where it was; it wanders off drawing a limb; and when it hits the matching ] it teleports straight back to the fork to grow the next limb from the same spot. Nested brackets give branches-on-branches — a tree. For example, with a turn angle of about 25^{\circ}, the short string

F [ + F ] F [ - F ] F

draws a trunk (F) that sprouts a left twig ([+F]), continues up (F), sprouts a right twig ([-F]), and finishes the trunk (F). Feed that same shape back into the rule F \to F[+F]F[-F]F a few times and each F becomes another little sprig — the whole thing bushes out into the plant below.

Watching it grow

Here is the identical rule F \to F[+F]F[-F]F from the axiom F, turtle-drawn at two iteration depths. The left plant has been rewritten twice; the right plant three times. Nothing changed but the number of iterations — one extra pass replaces every segment of the left plant with a whole miniature copy of the left plant, and the silhouette fills in. Deeper iteration, denser plant.

This is also the key to animating growth. If you interpolate the turtle's segment lengths from the shallow figure toward the deep one — or, in a parametric L-system, advance an "age" parameter continuously — the plant appears to sprout in real time: a seedling unfurling into a bush over a few seconds of screen time.

Making them natural: stochastic and parametric L-systems

A single deterministic rule gives a single perfect plant — and a field of clones looks fake. Two extensions fix this and are the workhorses of production plant generation.

Together they turn the toy machine into something that can dress a whole landscape: scatter a stochastic-parametric L-system across a terrain with a different random seed and a different age at each instance, and every plant is unique yet unmistakably the same species.

Two mistakes bite everyone the first time. First: the rewriting is parallel. It is tempting to sweep left to right and expand each symbol as you meet it — but if you do that on A \to AB,\ B \to A, the first A you rewrite drops a fresh B into the string that you then rewrite again in the same pass, and you get a longer, wrong string. Every symbol must be expanded from the original generation, all at once — build the new string in a separate buffer and only then swap it in.

Second: iteration explodes. Each pass multiplies the string length (that plant rule turns one F into five, so the count grows like 5^n). Ten iterations of a modest rule is already millions of symbols and will freeze your renderer. Always cap the depth — plants look complete by four to six iterations, and you gain almost nothing visible past that while paying exponentially more.

Yes — L-systems draw famous fractals, not just plants. Take axiom F, rule F \to F+F--F+F with a turn angle of 60^{\circ}, and no brackets at all: the turtle traces the Koch curve, and three of them arranged in a triangle make the Koch snowflake. Change the rule to F \to F-F+F+F-F at 90^{\circ} and you get a Koch island; a dragon curve, a Sierpiński triangle and the Hilbert space-filling curve are all just different alphabets and angles. Plants are the headline use, but the turtle-plus-grammar machine is a general fractal factory.