Skip to the plate
FORMA PUBLIC DOMAIN GENERATIVE ATLAS / ED. 0.28
Plate 78, Langford Attractor: a still of the flow / torus bifurcation plate as the atlas renders it, in the attractors accent.

PL. 78  ·  ATTRACTORS / FLOW / TORUS BIFURCATION

Langford Attractor

William F. Langford, 1984

OPEN THE LIVE PLATE ▸

DEFINITION

ẋ = (z − b)x − d·y
ẏ = d·x + (z − b)y
ż = c + a·z − z³/3 − (x² + y²)(1 + e·z) + f·z·x³

NOTES

A torus that folds into a shell — the trajectory winds around a rising bowl, turns over its rim and drops back through the middle. It is all over the internet under the name "Aizawa", and that attribution appears to have no paper behind it: the equations are not in Aizawa’s published work. They are in Langford’s 1984 study of torus bifurcations, which is where this plate credits them. The name a figure travels under and the name on the mathematics are not always the same thing, and when they differ this atlas prints the second.

PROVENANCE

Origin
W. F. Langford, "Numerical studies of torus bifurcations", International Series of Numerical Mathematics, 1984
Standing
Public domain — a system of differential equations
Constants
a = 0.95, b = 0.7, c = 0.6, d = 3.5, e = 0.25, f = 0.1 is the set the figure is usually drawn from. e and f are LOCKED from regenerate: they are small shape terms, and f in particular is what folds the rim — jitter there flattens the shell into a plain torus
Source
doi:10.1007/978-3-0348-6256-1_19

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. 78 · LANGFORD ATTRACTOR — William F. Langford, 1984
//   ẋ = (z − b)x − d·y
//   ẏ = d·x + (z − b)y
//   ż = c + a·z − z³/3 − (x² + y²)(1 + e·z) + f·z·x³
// 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=langford

float p_a = 0.95 + chf('a_tweak');    // a — z gain · live 0.8 .. 1.05
float p_b = 0.7 + chf('b_tweak');     // b — radius · live 0.55 .. 0.85
float p_c = 0.6 + chf('c_tweak');     // c — lift · live 0.45 .. 0.75
float p_d = 3.5 + chf('d_tweak');     // d — rotation · live 2.6 .. 4.4
float p_e = 0.25 + chf('e_tweak');    // e — coupling · live 0.18 .. 0.32
float p_f = 0.1 + chf('f_tweak');     // f — fold · live 0.04 .. 0.16

// 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.004, 34000 steps from
// (0.1, 0, 0), the first 4000 discarded as transient. The system rotates
// about its z axis, conventionally vertical; mapped onto Houdini's y-up.
int   forma_steps = 34000;
int   forma_skip  = 4000;
float forma_dt    = 0.004;

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 = (z - p_b) * x - p_d * y;
    float dy = p_d * x + (z - p_b) * y;
    float dz = p_c + p_a * z - z * z * z / 3.0
             - (x * x + y * y) * (1.0 + p_e * z) + p_f * z * x * x * x;
    x += dx * forma_dt;  y += dy * forma_dt;  z += dz * forma_dt;
    if (!isfinite(x) || !isfinite(z)) break;
    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. 78 · LANGFORD ATTRACTOR — William F. Langford, 1984
//   ẋ = (z − b)x − d·y
//   ẏ = d·x + (z − b)y
//   ż = c + a·z − z³/3 − (x² + y²)(1 + e·z) + f·z·x³
// 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=langford

// 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.95 + forma_tweak("a_tweak");     // a — z gain · live 0.8 .. 1.05
var p_b    = 0.7 + forma_tweak("b_tweak");      // b — radius · live 0.55 .. 0.85
var p_c    = 0.6 + forma_tweak("c_tweak");      // c — lift · live 0.45 .. 0.75
var p_d    = 3.5 + forma_tweak("d_tweak");      // d — rotation · live 2.6 .. 4.4
var p_e    = 0.25 + forma_tweak("e_tweak");     // e — coupling · live 0.18 .. 0.32
var p_f    = 0.1 + forma_tweak("f_tweak");      // f — fold · live 0.04 .. 0.16
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.513494668295607;   // 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 Langford (Aizawa) system, the plate's own 34,000
// steps of dt = 0.004 from (0.1, 0, 0), the first 4,000 discarded, the shell
// lowered by 1.1 so it sits centred on its own axis. The page's view: the x–y
// plane turns at 0.09 rad/s, z is the screen vertical, 1/3.4 of the shorter
// side. Every second point is emitted.
var x = 0.1, y = 0, z = 0, dt = 0.004;
var DEG = Math.PI / 180;
var rot = forma_t * 0.09 + p_view * DEG, co = Math.cos(rot), si = Math.sin(rot);
var s = Math.min(forma_W, forma_H) / 3.4, cx = forma_W / 2, cy = forma_H / 2;
var pts = [];
for (var i = 0; i < 34000; i++){
  var dx = (z - p_b) * x - p_d * y;
  var dy = p_d * x + (z - p_b) * y;
  var dz = p_c + p_a * z - z * z * z / 3 - (x * x + y * y) * (1 + p_e * z) + p_f * z * x * x * x;
  x += dx * dt; y += dy * dt; z += dz * dt;
  if (!isFinite(x) || !isFinite(z)) break;
  if (i > 4000 && (i & 1) === 0){
    var zz = z - 1.1;
    pts.push(forma_pt(cx + (x * co + y * si) * s, cy - zz * s));
  }
}
createPath(pts, [], [], false);