🌿 Mathematics · Computer Graphics
πŸ“… June 2026⏱ 14 min🟑 Beginner–Intermediate

L-Systems & Procedural Plants: Grammar Theory to 3D Trees

In 1968 biologist Aristid Lindenmayer invented a string-rewriting formalism to model the growth of algae. That same mathematical framework β€” now called an L-system β€” underlies the procedurally generated trees in The Witcher 3, the fractal ferns of early computer art, and sophisticated plant-growth models used in botany research today.

1. String Rewriting: the Core Idea

An L-system (Lindenmayer system) is a formal grammar defined by three components:

At each generation step, every symbol in the string is simultaneously replaced by its production. This parallel rewriting is what distinguishes L-systems from regular grammars (which rewrite one symbol at a time) and why they capture self-similar biological growth so naturally.

// Algae growth (Lindenmayer's original 1968 example) Alphabet: { A, B } Axiom: A Rules: A β†’ AB B β†’ A Generation 0: A Generation 1: AB Generation 2: ABA Generation 3: ABAAB Generation 4: ABAABABA Generation 5: ABAABABAABAAB String lengths: 1, 2, 3, 5, 8, 13 … β†’ Fibonacci sequence! (Length ratio β†’ golden ratio Ο† β‰ˆ 1.618)

The Fibonacci sequence emerges naturally from a two-symbol L-system illustrating how simple rewriting rules produce rich mathematical structure. The branching counts in plant phyllotaxis (the spiral packing of seeds in a sunflower head, scales on a pine cone) follow the same sequence β€” L-systems provide a mechanistic explanation for why.

2. Turtle Graphics Interpretation

A string of symbols is just text until we assign it geometric meaning. Turtle graphics provides that mapping: imagine a turtle holding a pen, carrying a position and heading. Symbols command the turtle's movement:

Standard turtle symbol interpretation: F β€” move forward by step length d, draw a line segment f β€” move forward by d, do NOT draw (pen up) + β€” turn left by angle Ξ΄ - β€” turn right by angle Ξ΄ | β€” turn 180Β° (reverse direction) [ β€” push current state (position, heading) onto a stack ] β€” pop state from stack (return to saved position) & β€” pitch down by Ξ΄ (3D: rotate around left axis) ^ β€” pitch up by Ξ΄ (3D: rotate around left axis) \ β€” roll left by Ξ΄ (3D: rotate around heading axis) / β€” roll right by Ξ΄ (3D: rotate around heading axis) | β€” turn 180Β°

The stack bracket symbols [ and ] are what enable branching: push the turtle state before going down a branch, then pop it to return to the branch point and continue. Every plant's fork is a […] sub-string.

Interpretation is separate from grammar: The same L-system string can be rendered with different turtle parameters (different step length, angle, 2D vs 3D) to produce wildly different visuals. Conversely, the same visual can arise from different grammars. This separation of generation (grammar) from rendering (turtle) is a key design feature.

3. Classic DOL-System Examples

A DOL-system (Deterministic, context-free, 0-predecessor) is the simplest class: each symbol has exactly one rewrite rule and no context is checked. Most fractal plant illustrations use DOL-systems.

Koch Snowflake

Alphabet: { F, +, - } Axiom: F--F--F Rule: F β†’ F+F--F+F Angle Ξ΄: 60Β° Generation 2 produces the Koch snowflake outline. Each F segment is replaced by 4 sub-segments β†’ perimeter Γ— 4/3 each generation. After n generations: perimeter = (4/3)ⁿ Γ— original β†’ ∞ (fractal)

Dragon Curve

Alphabet: { F, G, +, - } Axiom: F Rules: F β†’ F+G G β†’ F-G Angle Ξ΄: 90Β° The dragon curve is the limit shape obtained by repeatedly folding a strip of paper in half in the same direction.

Bush / Tree Form

Alphabet: { F, +, -, [, ] } Axiom: F Rule: F β†’ FF-[-F+F+F]+[+F-F-F] Angle Ξ΄: 22.5Β° Generation 4 produces a recognisable 2D plant silhouette. The [ ] brackets create the branching structure.

Barnsley Fern (via IFS β€” analogous spirit)

The Barnsley fern is generated by an Iterated Function System rather than a strict L-system, but captures the same idea of self-similar replacement. An L-system equivalent uses 4 rules to produce frond, leaflet, and petiole structures at different scales.

4. Stochastic L-Systems for Natural Variation

Deterministic L-systems produce geometrically perfect, too-regular structures β€” trees that look stamped from a mould. Real plants have variation: slightly different branch angles, unequal branch lengths, asymmetric crowns. Stochastic L-systems assign probabilities to competing rules for the same symbol:

// Two competing rules for F: F β†’(0.7) F[+F]F[-F]F // 70% probability F β†’(0.3) F[+F]F // 30% probability Each time F is rewritten, a random draw selects the rule. Different random seeds β†’ different but structurally similar trees. Probabilities must sum to 1.0 for each predecessor symbol.

The results look remarkably biological. Each call to generate with a different random seed produces a unique tree, yet all instances share the same overall size, branching density, and character β€” exactly as conspecific trees in a forest resemble each other without being identical.

For reproducible procedural content in games, the random seed is stored per-object. Given the same seed and grammar, the same tree is always regenerated without storing the full geometry β€” saving significant memory for large forests.

5. Context-Sensitive L-Systems

In a context-sensitive L-system (IL-system or 2L-system), a symbol's rewriting may depend on its neighbours in the string. This models inter-cell signalling β€” information propagating through a biological structure:

// Context-sensitive rule notation left < symbol > right β†’ replacement Convention: left < A > right matches A only when preceded by left and followed by right. Example: propagation of a signal through a filament Alphabet: { a, b, B } Axiom: baaaaaaaa (one "b" signal at left end) Rules: b < a > β†’ b (signal b advances into a to its right) b β†’ b (b at position without right context stays b) Generation 0: baaaaaaaa Generation 1: bbaaaaaaa Generation 2: bbbaaaaaaa ... The "b" signal propagates to the right one cell per step.

Context-sensitive rules let the grammar model:

These biologically motivated models bridge pure mathematics and plant physiology, and were central to Lindenmayer's original research goals.

6. Parametric L-Systems

In parametric L-systems, each symbol carries numeric parameters, and production rules are conditional on those parameters. This enables continuous plant growth models where branch lengths and angles change with age:

// Parametric symbol notation: A(t) β€” symbol A with parameter t // Rule notation: // A(t) : t > 0 β†’ F(t) [ +(30) A(t-1) ] [ -(30) A(t-1) ] Axiom: A(5) (start with symbol A, age 5) Rule: A(t): t > 0 β†’ F(t) [+(30) A(t-1)] [-(30) A(t-1)] A(t): t == 0 β†’ L (terminal: leaf symbol) Generation 0: A(5) Generation 1: F(5) [+(30) A(4)] [-(30) A(4)] Generation 2: F(5) [+(30) F(4)[+(30)A(3)][-(30)A(3)]] [-(30) F(4)…] ... Each A(t) spawns two child branches with age t-1. A(0) becomes a leaf. The stem segment F(t) has length proportional to t.

This models apical dominance β€” the tip of a plant branch growing vigorously while lateral branches weaken. A secondary production could reduce the parameter of subordinate branches, naturally producing the conical crown shape of fir trees.

Prusinkiewicz and Lindenmayer's 1990 book The Algorithmic Beauty of Plants (freely available online) catalogs dozens of parametric L-systems matching measured botanical data. It remains the definitive reference for the field.

7. 3D Plant Generation

Extending from 2D turtle to 3D requires tracking a full 3D orientation frame. The turtle carries three orthogonal vectors: H (heading), L (left), and U (up). Rotation commands apply rotation matrices to this frame:

3D turtle state: (position, H, L, U) Initial: H = (0,1,0), L = (-1,0,0), U = (0,0,1) Rotation around U (yaw): + and - symbols, angle Ξ΄ Rotation around L (pitch): & (down) and ^ (up), angle Ξ΄ Rotation around H (roll): \ (left) and / (right), angle Ξ΄ F command: move by d in direction H new_position = position + d Γ— H Stack [/]: push (position, H, L, U) triplet Stack ]: pop triplet (restore position and orientation) Tropism (gravity/light response): Apply a small correction torque Ο„ = e Γ— H at each segment, where e is the elastic coefficient and H the heading vector. This bends branches downward (gravity) or toward light.

Tropism β€” the bending of growth toward or away from a stimulus β€” is modelled by a small rotation correction applied at every branch segment. A heavy branch sags under gravity (negative geotropism: e Γ— gravity_vector); a leaf petiole twists toward the sun (phototropism).

Geometry Output and Instancing

For real-time rendering, the turtle's segments are not drawn as individual line primitives but grouped into meshes:

8. Applications in Games & Visualisation

L-systems are a staple of procedural content generation (PCG) in games and visualisation software:

Implementation tip: A minimal L-system renderer needs three things: a string expander (apply rules N times), a turtle interpreter (walk the string, maintain a stack), and a drawing primitive (canvas line, Three.js BufferGeometry, etc.). The full working implementation in 2D is under 100 lines of JavaScript. Start DOL-system, fixed angle, then add stochastic and 3D extensions incrementally.

The deeper lesson of L-systems is that complex, apparently designed structure can arise from very simple local rules applied iteratively. This resonates far beyond botany: similar pattern-forming mechanisms appear in animal coat patterns (reaction-diffusion), urban street networks, river tributaries, and lung bronchial trees β€” all exhibiting statistical self-similarity well described by variants of the same rewriting framework.