DEFINITION
xₙ₊₁ = sin(a·yₙ) + c·cos(a·xₙ) yₙ₊₁ = sin(b·xₙ) + d·cos(b·yₙ)
NOTES
A sibling of the de Jong map with the cosine terms scaled rather than subtracted. The result tends toward smoke and ribbon rather than veil. Pickover catalogued dozens of these in the late 1980s while looking for what he called "biomorphs".
PROVENANCE
- Origin
- Clifford A. Pickover, from his work on iterated maps
- Standing
- Public domain — an iterated map
- Constants
- Keep |c| and |d| near 1 for the densest structure
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. 09 · CLIFFORD MAP — Clifford A. Pickover
// xₙ₊₁ = sin(a·yₙ) + c·cos(a·xₙ)
// yₙ₊₁ = sin(b·xₙ) + d·cos(b·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=clifford
float p_a = -1.4 + chf('a_tweak'); // a · live -3 .. 3
float p_b = 1.6 + chf('b_tweak'); // b · live -3 .. 3
float p_c = 1 + chf('c_tweak'); // c · live -2 .. 2
float p_d = 0.7 + chf('d_tweak'); // d · live -2 .. 2
// 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.
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) + p_c * cos(p_a * x);
float ny = sin(p_b * x) + p_d * cos(p_b * 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));
float u = float(i) / float(forma_pts + forma_skip);
setpointattrib(0, "Cd", pt, forma_ramp(0.8 + 0.3 * u));
}