Skip to the plate
FORMA PUBLIC DOMAIN GENERATIVE ATLAS / ED. 0.28
Plate 01, Lissajous Figure: a still of the parametric / standing wave plate as the atlas renders it, in the curves accent.

PL. 01  ·  CURVES / PARAMETRIC / STANDING WAVE

Lissajous Figure

Nathaniel Bowditch, 1815 · Jules Lissajous, 1857

OPEN THE LIVE PLATE ▸

DEFINITION

x(u) = A·sin(a·u + δ)
y(u) = B·sin(b·u)

NOTES

Two perpendicular sinusoids plotted against each other. When a and b are small whole-number ratios the path closes into a standing knot; irrational ratios never close and fill the box. Bowditch found them with a compound pendulum forty years before Lissajous found them with mirrors and a tuning fork.

PROVENANCE

Origin
Bowditch (1815), independently Lissajous (1857)
Standing
Public domain — 19th-century mathematics
Constants
δ animates continuously; a and b set the ratio

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. 01 · LISSAJOUS FIGURE — Nathaniel Bowditch, 1815 · Jules Lissajous, 1857
//   x(u) = A·sin(a·u + δ)
//   y(u) = B·sin(b·u)
// 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=lissajous

float p_a     = 3 + chf('a_tweak');           // a — horizontal frequency · live 1 .. 12
float p_b     = 4 + chf('b_tweak');           // b — vertical frequency · live 1 .. 12
float p_delta = 0.6 + chf('delta_tweak');     // δ — phase offset · live 0 .. 3.14

// The plate's own colour: FORMA's CURVES 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.11 + 0.1196 * cos(6.28318530718 * (t + 0)),
    0.46 + 0.5 * cos(6.28318530718 * (t + 0.05)),
    0.2453 + 0.2667 * cos(6.28318530718 * (t + 0.1)));
}

// One closed period of the figure: u over 2π at unit amplitude. Integer
// frequencies close the curve; the phase δ tilts it out of degeneracy.
int forma_n = 1600;

float TAU = 6.28318530718;
int prim = addprim(0, "polyline");
for (int i = 0; i <= forma_n; i++){
    float u = float(i) / float(forma_n) * TAU;
    // canvas y runs down; negated so the figure sits as the plate shows it
    int pt = addpoint(0, set(sin(p_a * u + p_delta), -sin(p_b * u), 0.0));
    // colour sweeps the bright lobe of the ramp along the curve
    float uu = float(i) / float(forma_n);
    setpointattrib(0, "Cd", pt, forma_ramp(0.8 + 0.3 * uu));
    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. 01 · LISSAJOUS FIGURE — Nathaniel Bowditch, 1815 · Jules Lissajous, 1857
//   x(u) = A·sin(a·u + δ)
//   y(u) = B·sin(b·u)
// 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 CURVES accent, #3DFF88. Animation runs on time.
// https://forma-gen.com/#plate=lissajous

// 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     = 3 + forma_tweak("a_tweak");         // a — horizontal frequency · live 1 .. 12
var p_b     = 4 + forma_tweak("b_tweak");         // b — vertical frequency · live 1 .. 12
var p_delta = 0.6 + forma_tweak("delta_tweak");   // δ — phase offset · live 0 .. 3.14

// 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.09191389987245202;   // 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]; }

// One closed period of the figure: u over 2π at the plate's own amplitude,
// R = 0.42 of the shorter side. Integer frequencies close the curve; δ tilts
// it out of degeneracy. The page's comet is Trim Paths: animate End from 0 to
// 100% over 18 s and set Offset to follow, and the figure traces itself.
var R = Math.min(forma_W, forma_H) * 0.42, N = 1600;
var pts = [];
for (var i = 0; i <= N; i++){
  var u = i / N * Math.PI * 2;
  pts.push(forma_pt(forma_W / 2 + R * Math.sin(p_a * u + p_delta),
                    forma_H / 2 + R * Math.sin(p_b * u)));
}
createPath(pts, [], [], true);