reas_processing · lindenmayer
Lindenmayer L-system + Turtle Rendering
An axiom string is rewritten by parallel production rules for a fixed number of iterations, then interpreted by a 2-D turtle: 'F' walks forward, '+/-' turn left/right, '['/']' push/pop state. The output is the canonical fractal bush/tree/star pattern that appears in Casey Reas's *Form+Code in Design, Art, and Architecture* under the 'Recursion' chapter. Increasing iterations adds depth; step length scales down so the figure stays inside the canvas.
Original: http://formandcode.com
▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.
Math essence
Each iteration replaces every symbol S in the string by rules[S] (or S unchanged). The turtle maintains (x, y, theta) plus a stack; F pushes a line segment, +/- rotate by angle_deg, [/] save/restore state. Rendering is an n-segment linspace per F step blended onto the canvas with a 3x3 ink stamp for thickness.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 600 | 200–1400 | Square canvas side length. |
preset | str | bush | — | Built-in axiom+rules: bush, stochastic_tree, fractal_weed, koch_snowflake. |
angle_deg | float | 22.5 | 5–90 | Turn angle for +/-. |
iterations | int | 4 | 1–8 | Rewriting depth (step(n=1) increments this). |
start_step | float | 6 | 0.5–30 | Step length at iteration 0; shrinks by 0.72 each iteration. |
start_angle_deg | float | -90 | -180–180 | Initial turtle heading. -90 makes the figure grow upward. |
ink_alpha | float | 0.85 | 0.1–1 | Per-pixel blend opacity when stamping ink. |
bg_color | tuple | 252,248,240 | — | Background color. |
ink_color | tuple | 30,55,40 | — | Stroke color. |
seed | int | null | 0–999999 | Optional RNG seed (for future stochastic rules). |
Reference
First 60 lines of reference.py. Full source:
library_external/reas_processing/lindenmayer/reference.py
from __future__ import annotations
from typing import ClassVar
import numpy as np
PRESETS: dict[str, dict] = {
"bush": {
"axiom": "F",
"rules": {"F": "F[+F]F[-F]F"},
"angle": 22.5,
"iterations": 4,
"start_step": 6.0,
},
"stochastic_tree": {
"axiom": "F",
"rules": {"F": "F[+F]F[-F][F]"},
"angle": 25.0,
"iterations": 5,
"start_step": 8.0,
},
"fractal_weed": {
"axiom": "X",
"rules": {"X": "F+[[X]-X]-F[-FX]+X", "F": "FF"},
"angle": 22.5,
"iterations": 5,
"start_step": 5.0,
},
"koch_snowflake": {
"axiom": "F++F++F",
"rules": {"F": "F-F++F-F"},
"angle": 60.0,
"iterations": 4,
"start_step": 8.0,
},
}
class Lindenmayer:
"""Lindenmayer L-system string rewriting with 2-D turtle rendering.
An axiom is iteratively rewritten using stochastic or deterministic
production rules, then interpreted by a turtle drawing primitive
(``F`` = forward, ``+/-`` = turn, ``[`` / ``]`` = push / pop). The
output is a graceful fractal curve grown once and rendered onto the
canvas. This is the canonical L-system + turtle pipeline featured in
Aristid Lindenmayer's biological models and in Casey Reas's
``Form+Code`` chapter on recursive growth.
"""
family: ClassVar[str] = "reas_processing"
sketch: ClassVar[str] = "lindenmayer"
def __init__(
self,
dim: int = 600,
preset: str = "bush",
axiom: str | None = None,
rules: dict[str, str] | None = None, Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/reas_processing/lindenmayer/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from reas · processing
2-D Totalistic Cellular Automaton (Conway + variants)
reas_processing · wolframCA2D
Each cell looks at its 8 Moore neighbors and applies a totalistic rule.
Gray-Scott Reaction-Diffusion
reas_processing · grayScottRD
Two scalar species U and V diffuse on a square grid with rates Du and Dv and react with feed F and kill k.
Particle-Spring Cloth (Verlet + Hooke)
reas_processing · particleSpring
A rectangular grid of free particles is connected by Hooke's-law springs at rest length 'spacing'.
Perlin Streamlines
reas_processing · perlinStreamlines
A 2-D vector field is sampled from one or more octaves of Perlin gradient noise.
Voronoi Diagram from Random Seeds
reas_processing · voronoi
Every pixel on the canvas is colored with the palette color of the seed point closest to it.
Wolfram Elementary 1-D Cellular Automaton
reas_processing · wolframCA1D
Each row of the canvas is one generation of a Wolfram elementary cellular automaton.