Strange Attractors

Philosophy

Strange attractors visualize deterministic chaos — systems governed by precise equations that nonetheless produce behavior so complex it appears random. The Lorenz attractor, discovered in 1963 while modeling weather, revealed that tiny differences in starting conditions lead to wildly divergent paths — the “butterfly effect.”

The philosophical weight: the universe can be lawful and unpredictable at the same time. Strange attractors are the shapes chaos makes when it settles — never repeating, never escaping, infinitely detailed. They are portraits of order hiding inside disorder.

Key Algorithms

Lorenz Attractor

dx/dt = σ(y - x)
dy/dt = x(ρ - z) - y
dz/dt = xy - βz

Classic parameters: σ=10, ρ=28, β=8/3. Produces the iconic butterfly shape. Integrate with small dt (0.005-0.01) and draw the 3D path projected to 2D.

Parameters: σ (sigma), ρ (rho), β (beta), dt, rotation angle, trail length

Clifford Attractor

x(n+1) = sin(a·y(n)) + c·cos(a·x(n))
y(n+1) = sin(b·x(n)) + d·cos(b·y(n))

Four parameters (a, b, c, d) that produce dramatically different patterns. Iterate millions of times, plotting each point with low opacity.

Interesting parameter ranges: a,b ∈ [-2, 2], c,d ∈ [-2, 2]

Parameters: a, b, c, d, iterations per frame, point opacity, color mode

De Jong Attractor

x(n+1) = sin(a·y(n)) - cos(b·x(n))
y(n+1) = sin(c·x(n)) - cos(d·y(n))

Similar to Clifford but produces different structural families. Very sensitive to parameters.

Hénon Map

x(n+1) = 1 - a·x(n)² + y(n)
y(n+1) = b·x(n)

Classic: a=1.4, b=0.3. Produces a fractal curve. Simple but foundational.

Thomas Attractor

dx/dt = sin(y) - b·x
dy/dt = sin(z) - b·y
dz/dt = sin(x) - b·z

Dissipation parameter b controls complexity. Near b=0.2, produces beautiful 3D knots.

Notable Artists & Works

p5.js Implementation Notes

Functional Iteration Pattern

The thi.ng/transducers ecosystem models attractor iteration as composable functional pipelines rather than imperative loops:

// Attractor as a pure function: state → next_state
function cliffordStep(a, b, c, d) {
  return ([x, y]) => [
    Math.sin(a * y) + c * Math.cos(a * x),
    Math.sin(b * x) + d * Math.cos(b * y),
  ];
}

// Generate N points as a lazy sequence
function* attractorSequence(stepFn, start, n) {
  let state = start;
  for (let i = 0; i < n; i++) {
    state = stepFn(state);
    yield state;
  }
}

// Collect points as data, then render (enables both Canvas and SVG output)
const step = cliffordStep(a, b, c, d);
const points = [...attractorSequence(step, [0.1, 0.1], 100000)];

This separation of iteration from rendering allows:

Perceptual Color for Attractors

Point-cloud attractors benefit greatly from perceptual color mapping:

See references/color-science.md for cosine gradient presets, Oklab conversion functions, and LCH theme generation.

Demos in the gallery