PL. 08 · ATTRACTORS / MAP / ITERATED
De Jong Map
Peter de Jong, popularised 1980s
OPEN THE LIVE PLATE ▸DEFINITION
xₙ₊₁ = sin(a·yₙ) − cos(b·xₙ) yₙ₊₁ = sin(c·xₙ) − cos(d·yₙ)
NOTES
Four constants, two lines, and an unreasonable amount of structure. Plotted as a density histogram over a few hundred thousand iterations, the map produces veils and caustics that look photographed rather than computed. Almost every parameter set gives something; a few give something extraordinary.
PROVENANCE
- Origin
- Attributed to Peter de Jong; circulated via Scientific American
- Standing
- Public domain — an iterated map
- Constants
- Sweep any one constant slowly and the whole figure breathes
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. 08 · DE JONG MAP — Peter de Jong, popularised 1980s
// xₙ₊₁ = sin(a·yₙ) − cos(b·xₙ)
// yₙ₊₁ = sin(c·xₙ) − cos(d·yₙ)
// 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=dejong
float p_a = 1.641 + chf('a_tweak'); // a · live -3 .. 3
float p_b = 1.902 + chf('b_tweak'); // b · live -3 .. 3
float p_c = 0.316 + chf('c_tweak'); // c · live -3 .. 3
float p_d = 1.525 + chf('d_tweak'); // d · live -3 .. 3
// 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)));
}
// The exposure replayed as a point cloud: iterate from (0.1, 0.1) and discard
// the first 20 landings, as the plate's expose() does — the walk toward the
// attractor is not the attractor.
int forma_pts = 120000;
int forma_skip = 20;
float x = 0.1, y = 0.1;
for (int i = 0; i < forma_pts + forma_skip; i++){
float nx = sin(p_a * y) - cos(p_b * x);
float ny = sin(p_c * x) - cos(p_d * y);
x = nx; y = ny;
if (i < forma_skip) continue;
// canvas y runs down; negated so the figure sits as the plate shows it
int pt = addpoint(0, set(x, -y, 0.0));
// colour sweeps the bright lobe of the ramp across the exposure
float u = float(i) / float(forma_pts + forma_skip);
setpointattrib(0, "Cd", pt, forma_ramp(0.8 + 0.3 * u));
}