Article Generative Art · ≈ ⏱ 8 min read

L-Systems and Turtle Graphics

A Lindenmayer system rewrites a short string over and over according to a handful of rules, and a "turtle" — a cursor that remembers a position and a heading — turns the result into ferns, trees, dragon curves, and city street networks.

TL;DR: An L-system generates complex shapes from a tiny rule: start with one symbol and repeatedly replace it using a fixed set of production rules until the string is thousands of characters long. A turtle then reads that string left to right, moving, turning, and branching with a stack, to draw the result as ferns, trees, Koch curves, dragon curves, and Sierpiński triangles.

1. What is an L-system?

A Lindenmayer system (L-system) was introduced in 1968 by biologist Aristid Lindenmayer to model the growth of algae and plants cell by cell. Its core idea is deceptively simple: start with one symbol (the axiom), and repeatedly replace every symbol in the string with a longer string according to a fixed set of production rules. After a handful of iterations, a single character has grown into a string thousands of characters long — and if you interpret that string as drawing instructions, you get a recognisable plant, snowflake, or curve.

The magic is that L-systems are context-free (in the simplest variant): the rewrite rule for a symbol doesn't care what surrounds it, yet the aggregate result still captures the self-similar branching you see in real ferns and trees, because biological growth itself is largely a repeated local rule applied at every growing tip.

Fractal cousin

L-systems are a general-purpose fractal generator, closely related to iterated function systems (IFS). The Koch snowflake and dragon curve — both classic fractals — have equally clean L-system definitions, alongside more organic shapes like Barnsley's fern.

2. String rewriting: axiom and rules

An L-system is defined by three things: an alphabet of symbols, an axiom (the starting string), and a set of production rules mapping each symbol to a replacement string. Take the simplest possible example:

Algae growth (Lindenmayer's original example) Axiom: A
Rules: A → AB, B → A

Applying the rules generation by generation:

Gen 0: A
Gen 1: AB
Gen 2: ABA
Gen 3: ABAAB
Gen 4: ABAABABA

The string length follows the Fibonacci sequence exactly — a reminder that L-systems, growth patterns, and number sequences are often the same idea wearing different clothes.

3. Turtle graphics: from string to pixels

A string of letters is not a picture yet. Turtle graphics (from Seymour Papert's Logo language, 1967) gives meaning to each character by interpreting the string as a sequence of commands for an imaginary turtle that carries a position (x, y) and a heading angle:

Move forward and draw x += cos(heading) · stepLength
y += sin(heading) · stepLength
drawLine(prevX, prevY, x, y)

Run the turtle through a whole rewritten string, character by character, and the line segments it draws trace out the shape encoded in the grammar.

4. The standard turtle alphabet

Symbol Meaning
F, G Move forward by one step, drawing a line
f Move forward by one step without drawing (a "jump")
+ Turn left (counter-clockwise) by the fixed angle δ
- Turn right (clockwise) by the fixed angle δ
[ Push the current state (position + heading) onto a stack
] Pop a state off the stack and make it current

Only two numbers control the whole visual family: the step length (how far each F moves) and the turn angle δ (how sharply + and - rotate the heading). Changing δ from 20° to 25° can turn a tidy geometric pattern into a wild organic one.

5. Branching with a stack: [ and ]

Plants branch — a stem splits into two, each of which may split again. A single turtle can only face one direction at a time, so branching is modelled with a stack: [ saves the turtle's current position and heading, the turtle draws a side branch, and ] restores the saved state so the main stem can continue exactly where it left off.

A simple branching plant Axiom: F
Rule: F → F[+F]F[-F]F
δ = 25°

After 4–5 generations, this three-line rule produces a recognisably bush-like silhouette — proof that most of the visual complexity of a plant is not encoded explicitly, it emerges from a short rule applied recursively.

6. Classic examples

Koch curve (fractal coastline)

Axiom: F
Rule: F → F+F--F+F
δ = 60°

Dragon curve

Axiom: FX
Rules: X → X+YF+, Y → -FX-Y
δ = 90°

Sierpiński triangle (arrowhead)

Axiom: A
Rules: A → B-A-B, B → A+B+A
δ = 60°

Barnsley-style fern

Axiom: X
Rules: X → F+[[X]-X]-F[-FX]+X, F → FF
δ = 25°
Stochastic L-systems

Real plants aren't perfectly self-similar. A common trick is a stochastic L-system: give a symbol two or more alternative replacement rules and pick between them randomly each time (weighted by probability). This breaks the mechanical regularity and produces far more convincing, nature-like variation between branches.

7. Pseudocode

Generating and drawing an L-system in two clear phases:

// Phase 1: string rewriting
function rewrite(axiom, rules, generations):
  s = axiom
  for g in range(generations):
    s = join(rules[c] or c for c in s)
  return s

// Phase 2: turtle interpretation
function drawTurtle(str, stepLength, angleDeg):
  x, y, heading = 0, 0, -90  // start pointing up
  stack = []

  for ch in str:
    if ch in "FG":
      nx = x + cos(heading) * stepLength
      ny = y + sin(heading) * stepLength
      drawLine(x, y, nx, ny)
      x, y = nx, ny
    elif ch == "f":
      x += cos(heading) * stepLength
      y += sin(heading) * stepLength
    elif ch == "+":
      heading += angleDeg
    elif ch == "-":
      heading -= angleDeg
    elif ch == "[":
      stack.push({x, y, heading})
    elif ch == "]":
      { x, y, heading } = stack.pop()

Note the separation of concerns: rewrite knows nothing about drawing, and drawTurtle knows nothing about grammar rules. The same turtle interpreter draws a Koch curve, a fern, or a dragon curve — only the axiom, rules, and angle change.

▶ Live Demo

🐢 Try the L-system simulation

Pick from 8 presets — Koch curve, dragon curve, Sierpiński arrowhead, Barnsley fern and more — and tune step length, angle and generation count live.

Open simulation →

🔗 Related Simulations

🌳Fractal Tree 🌊Flow Fields 🌃Generative City 🌀Spirograph