shiffman_pearson_textbook · recursiveTree
Stochastic Recursive Fractal Tree
Stack-based stochastic fractal tree from Shiffman's Nature of Code Ch. 8. Each generation spawns n_branches child branches, each rotated by a random angle drawn from a uniform distribution centered on branch_angle_deg with spread angle_jitter_deg (or a Gaussian when jitter_mode='normal'). Child length = parent_length * length_decay; thickness also decays. Recursion stops when length < 0.5 or levels > N. The deterministic version (jitter=0) reproduces Example 8.6; the stochastic version with leaf_size > 0 adds a red dot at each terminal branch tip, giving a flowering-tree look.
Original: https://natureofcode.com/fractals/
▶ 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
Iterative stack-based recursion (avoids Python recursion limit). For each branch at heading h and length L: x2 = x + L*cos(h), y2 = y + L*sin(h). Children: n = randint(n_min, n_max+1), angle = +/- jitter_angle drawn from uniform[a-j, a+j] or normal(a, j). Branch stamped to canvas with a disk brush of thickness that decays geometrically per level. Leaves stamped when leaf_size>0 at terminal branches.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 600 | 200–1400 | |
root_length | float | 130 | 20–400 | Trunk length (pixels). |
length_decay | float | 0.72 | 0.4–0.95 | Per-level length multiplier. |
branch_angle_deg | float | 25 | 5–90 | Mean branch angle from parent. |
angle_jitter_deg | float | 15 | 0–60 | Per-branch angle jitter. |
jitter_mode | str | uniform | — | |
n_branches_min | int | 2 | 1–5 | |
n_branches_max | int | 3 | 1–6 | Each parent spawns a random integer in [min, max] children. |
levels | int | 8 | 3–12 | |
trunk_thickness | float | 4 | 1–14 | |
thickness_decay | float | 0.72 | 0.4–0.95 | |
leaf_size | float | 0 | 0–12 | 0 = no leaves; otherwise radius in pixels. |
bg_color | tuple | 245,240,230 | — | |
ink_color | tuple | 50,35,25 | — | |
leaf_color | tuple | 180,70,60 | — | |
seed | int | null | 0–999999 |
Reference
First 60 lines of reference.py. Full source:
library_external/shiffman_pearson_textbook/recursiveTree/reference.py
from __future__ import annotations
from typing import ClassVar
import numpy as np
class RecursiveTree:
"""Stochastic recursive fractal tree — Nature of Code Ch. 8, Example 8.7.
Builds a branching fractal tree from a stack-based recursion. The root
trunk grows upward; at each generation it produces ``n_branches`` child
branches, each rotated by an angle drawn from a normal distribution
centered at ``branch_angle_deg`` with spread ``angle_jitter_deg`` (or a
uniform distribution in ``[-angle_jitter_deg, +angle_jitter_deg]`` when
``jitter_mode='uniform'`` — the textbook default). Each child's length
is the parent's length multiplied by ``length_decay``. Recursion stops
when the branch length drops below ``min_length`` (8 levels by default).
This is the textbook stochastic fractal tree from Shiffman's Example 8.7
'A Stochastic Tree', and is also covered in Pearson's *Generative Art*
as a Python/Processing canonical motif.
``step(n)`` does not strictly evolve — the tree is grown once and the
canvas is reused — but each call advances the random seed and re-grows
the tree, producing a new stochastic tree image so the corpus has
variation across step indices.
"""
family: ClassVar[str] = "shiffman_pearson_textbook"
sketch: ClassVar[str] = "recursiveTree"
def __init__(
self,
dim: int = 600,
root_length: float = 130.0,
length_decay: float = 0.72,
branch_angle_deg: float = 25.0,
angle_jitter_deg: float = 15.0,
jitter_mode: str = "uniform",
n_branches_min: int = 2,
n_branches_max: int = 3,
levels: int = 8,
trunk_thickness: float = 4.0,
thickness_decay: float = 0.72,
bg_color: tuple[int, int, int] = (245, 240, 230),
ink_color: tuple[int, int, int] = (50, 35, 25),
leaf_color: tuple[int, int, int] | None = None,
leaf_size: float = 0.0,
seed: int | None = None,
) -> None:
self.dim = dim
self.root_length = root_length
self.length_decay = length_decay
self.branch_angle_deg = branch_angle_deg
self.angle_jitter_deg = angle_jitter_deg
self.jitter_mode = jitter_mode
self.n_branches_min = n_branches_min
self.n_branches_max = n_branches_max
self.levels = levels Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/shiffman_pearson_textbook/recursiveTree/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from shiffman · pearson
Genetic Algorithm (Evolve Toward Target String)
shiffman_pearson_textbook · geneticAlgorithmString
A textbook genetic algorithm that evolves a population of binary strings toward a target ASCII string (default 'HELLO WORLD!').
Lindenmayer L-System (Textbook Formulation)
shiffman_pearson_textbook · lindenmayerTextbook
Lindenmayer L-system string rewriting with a 2-D turtle interpreter, the canonical textbook formulation used in both Shiffman's Nature of Code Ch.
Mandelbrot Set (Escape-Time Fractal)
shiffman_pearson_textbook · mandelbrotSet
The Mandelbrot set rendered by escape-time iteration of z = z^2 + c on a window of the complex plane.
Perlin Noise Flow Field
shiffman_pearson_textbook · perlinFlowField
A 2-D scalar field of Perlin gradient noise is sampled on a coarse grid; each cell is assigned a heading theta = 2*pi * n.
Random Walk / Drunkard's Walk
shiffman_pearson_textbook · randomWalkDrunkard
Many random walkers each start at the canvas center and take a stochastic 2-D step every tick.
Reynolds Boids (Separation / Alignment / Cohesion)
shiffman_pearson_textbook · boidsClassic
Reynolds' classic boids flocking model.