Skip to the plate
FORMA PUBLIC DOMAIN GENERATIVE ATLAS / ED. 0.28
Plate 41, Rössler Attractor: a still of the flow / folded band plate as the atlas renders it, in the attractors accent.

PL. 41  ·  ATTRACTORS / FLOW / FOLDED BAND

Rössler Attractor

Otto Rössler, 1976

OPEN THE LIVE PLATE ▸

DEFINITION

ẋ = −y − z
ẏ = x + a·y
ż = b + z(x − c)

NOTES

Rössler went looking for the simplest possible continuous chaos — one nonlinear term, against the Lorenz system’s two. The orbit spirals outward in the plane until the single z·x term throws it upward and folds it back into the middle, over and over. He liked to compare the mechanism to a taffy-pulling machine: stretch, fold, repeat, and two nearby points end up anywhere.

PROVENANCE

Origin
O. E. Rössler, "An Equation for Continuous Chaos", Physics Letters A 57, 1976
Standing
Public domain — a system of differential equations
Constants
a = b = 0.2, c = 5.7 is the classic parameter set
Source
doi:10.1016/0375-9601(76)90101-8

HOUDINI · VEX

The same published mathematics as a Detail Wrangle body. Paste it into a Wrangle with Run Over set to Detail; every constant is the published value plus a tweak channel, so Create Spare Parameters gives a slider that starts where the paper does.

// FORMA — PL. 41 · RÖSSLER ATTRACTOR — Otto Rössler, 1976
//   ẋ = −y − z
//   ẏ = x + a·y
//   ż = b + z(x − c)
// Paste into a Detail Wrangle (Run Over: Detail), no inputs needed.
// Written from the published mathematics, not adapted from any code.
// Constants arrive at their published values. Press the node's Create
// Spare Parameters button and every tweak becomes a slider — starting
// at 0, the published figure, and moving in the constant's own units.
// https://forma-gen.com/#plate=rossler

float p_a = 0.2 + chf('a_tweak');     // a — spiral gain · live 0.1 .. 0.32
float p_b = 0.2 + chf('b_tweak');     // b — lift · live 0.1 .. 1
float p_c = 5.7 + chf('c_tweak');     // c — fold · live 4.5 .. 8.5

// The plate's own colour: FORMA's ATTRACTORS accent as a cosine ramp,
// brightest near t = 0 and t = 1, near-black around t = 0.5.
vector forma_ramp(float t){
  return set(
    0.0956 + 0.1039 * cos(6.28318530718 * (t + 0)),
    0.4041 + 0.4392 * cos(6.28318530718 * (t + 0.05)),
    0.46 + 0.5 * cos(6.28318530718 * (t + 0.1)));
}

// waived: view — the azimuth the finished attractor is viewed from, and Houdini has a camera of its own
// Euler integration matching the plate: dt = 0.015, 30000 steps from
// (0.1, 0, 0), the first 600 discarded as transient. The same guard as the
// plate: constants jittered onto an escaping transient fold back to the
// start rather than filling the path with infinities.
int   forma_steps = 30000;
int   forma_skip  = 600;
float forma_dt    = 0.015;

// Rössler's z is the fold's lift, conventionally vertical; mapped onto
// Houdini's y-up.
float x = 0.1, y = 0.0, z = 0.0;
int prim = addprim(0, "polyline");
for (int i = 0; i < forma_steps; i++){
    float dx = -y - z;
    float dy = x + p_a * y;
    float dz = p_b + z * (x - p_c);
    x += dx * forma_dt;  y += dy * forma_dt;  z += dz * forma_dt;
    if (!isfinite(x + y + z) || abs(x) > 400.0){ x = 0.1; y = 0.0; z = 0.0; }
    if (i <= forma_skip) continue;
    int pt = addpoint(0, set(x, z, y));
    // colour sweeps the bright lobe of the ramp along the path
    float u = float(i - forma_skip) / float(forma_steps - forma_skip);
    setpointattrib(0, "Cd", pt, forma_ramp(0.8 + 0.3 * u));
    addvertex(0, prim, pt);
}

AFTER EFFECTS · EXPRESSION

The same published mathematics as a Shape Layer path expression. Paste it onto a Path property; every constant is the published value plus a Slider Control named _tweak, so a bare paste already draws the figure and each slider moves one constant in its own units. Trim Paths is the comet.

// FORMA — PL. 41 · RÖSSLER ATTRACTOR — Otto Rössler, 1976
//   ẋ = −y − z
//   ẏ = x + a·y
//   ż = b + z(x − c)
// After Effects port — paste onto a Shape Layer's Path property
// (Contents › Shape › Path). Written from the published mathematics, not
// adapted from any code. Constants arrive at their published values; add a
// Slider Control (Effect › Expression Controls) named <k>_tweak and that
// constant moves in its own units, starting at 0 — the published figure.
// The plate's comet and its reveal are Trim Paths; the stroke colour is
// FORMA's ATTRACTORS accent, #35E0FF. Animation runs on time.
// https://forma-gen.com/#plate=rossler

// A missing slider reads 0, so a bare paste already draws the figure.
function forma_tweak(n){ try { return effect(n)("Slider"); } catch (e){ return 0; } }
var p_a    = 0.2 + forma_tweak("a_tweak");      // a — spiral gain · live 0.1 .. 0.32
var p_b    = 0.2 + forma_tweak("b_tweak");      // b — lift · live 0.1 .. 1
var p_c    = 5.7 + forma_tweak("c_tweak");      // c — fold · live 4.5 .. 8.5
var p_view = 0 + forma_tweak("view_tweak");     // view azimuth ° · live -180 .. 180

// The frame: the plate's W × H canvas is this comp, with the origin at the
// layer's anchor; canvas y already runs down, as After Effects' does.
var forma_W = thisComp.width, forma_H = thisComp.height, forma_t = time;
var forma_phase = 0.35656306333839893;   // this plate's own fixed phase, as the page has it
function forma_pt(x, y){ return [x - forma_W / 2, y - forma_H / 2]; }

// Euler integration of the Rössler system, the plate's 30,000 steps of
// dt = 0.015 from (0.1, 0, 0), the first 600 discarded; a diverging state is
// folded back to the start rather than filling the path with Infinity. The
// z axis is lowered by 0.7c so the fold has room to rise. The page's view:
// the x–y plane turns at 0.11 rad/s, z is the screen vertical, 1/40 of the
// shorter side, centred at 0.6 of the height. Every second point is emitted.
var x = 0.1, y = 0, z = 0, dt = 0.015;
var DEG = Math.PI / 180;
var rot = forma_t * 0.11 + p_view * DEG, co = Math.cos(rot), si = Math.sin(rot);
var s = Math.min(forma_W, forma_H) / 40, cx = forma_W / 2, cy = forma_H * 0.6;
var pts = [];
for (var i = 0; i < 30000; i++){
  var dx = -y - z;
  var dy = x + p_a * y;
  var dz = p_b + z * (x - p_c);
  x += dx * dt; y += dy * dt; z += dz * dt;
  if (!isFinite(x + y + z) || Math.abs(x) > 400){ x = 0.1; y = 0; z = 0; }
  if (i > 600 && (i & 1) === 0){
    var zz = z - p_c * 0.7;
    pts.push(forma_pt(cx + (x * co + y * si) * s, cy - zz * s));
  }
}
createPath(pts, [], [], false);