Skip to the plate
FORMA PUBLIC DOMAIN GENERATIVE ATLAS / ED. 0.28
Plate 66, Buddhabrot: a still of the escape orbit / density plate as the atlas renders it, in the fractals accent.

PL. 66  ·  FRACTALS / ESCAPE ORBIT / DENSITY

Buddhabrot

Melinda Green, 1993

OPEN THE LIVE PLATE ▸

DEFINITION

for c that escape: plot every zₙ of the orbit
z₀ = 0,  zₙ₊₁ = zₙ² + c
density of visits, not escape time

NOTES

The Mandelbrot set rendered inside out. Instead of colouring each c by how fast it escapes, sample points at random, throw away the ones that stay bounded, and plot the whole trajectory of the ones that get away. Where those escaping orbits linger, the plate brightens. Green found the resulting figure — a seated form with a halo — in 1993, circulating it on the sci.fractals newsgroup, and it looks nothing like the set it comes from.

PROVENANCE

Origin
Melinda Green, 1993, circulated on the sci.fractals newsgroup
Standing
Public domain — a rendering method for a public-domain set
Constants
Orbit length bounds are locked: they set both the figure and the cost

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. 66 · BUDDHABROT — Melinda Green, 1993
//   for c that escape: plot every zₙ of the orbit
//   z₀ = 0,  zₙ₊₁ = zₙ² + c
//   density of visits, not escape time
// 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=buddhabrot

float p_iter = 280 + chf('iter_tweak');     // orbit limit · live 120 .. 600
float p_flr  = 12 + chf('flr_tweak');       // minimum orbit · live 4 .. 60

// The plate's own colour: FORMA's FRACTALS 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.46 + 0.5 * cos(6.28318530718 * (t + 0)),
    0.1389 + 0.151 * cos(6.28318530718 * (t + 0.05)),
    0.1912 + 0.2078 * cos(6.28318530718 * (t + 0.1)));
}

// The Mandelbrot set inside out: sample c at random over the plate's own
// window, iterate z² + c to the orbit limit, and keep the whole trajectory
// only if it escaped after at least the minimum orbit — the rejection is
// the entire method, and a c that stays bounded contributes nothing.
// Orbits are paid out whole, so the point budget — capped near the other
// exposures' — overshoots by at most one orbit. The sample count is hard-
// bounded so no tweak can hang the cook. Deterministic: c derives from
// random(counted seed), so every cook is the same figure.
// waived: res — the density lattice is the canvas display's histogram; this
// port emits the raw orbit points and bins nothing, so there is no grid for
// the constant to size
int forma_pts    = 120000;
int forma_maxtry = 200000;

int cap = int(rint(p_iter));
int flr = int(rint(p_flr));
int plotted = 0;
int rc = 1993;                    // the plate's own seed, counted upward
for (int s = 0; s < forma_maxtry; s++){
    if (plotted >= forma_pts) break;
    float cr = -2.1 + 3.2 * random(rc);  rc++;
    float ci = -1.5 + 3.0 * random(rc);  rc++;
    float zr = 0.0, zi = 0.0;
    float oxs[], oys[];           // the orbit, held until it proves it escapes
    int k = 0;
    while (k < cap && zr * zr + zi * zi < 4.0){
        float nr = zr * zr - zi * zi + cr;
        zi = 2.0 * zr * zi + ci;
        zr = nr;
        push(oxs, zr);  push(oys, zi);
        k++;
    }
    // bounded orbits never draw; short escapes only thicken the outer haze
    if (k >= cap || k < flr) continue;
    for (int i = 0; i < k; i++){
        // canvas y runs down; negated so the figure sits as the plate shows it
        int pt = addpoint(0, set(oxs[i], -oys[i], 0.0));
        // colour sweeps the bright lobe of the ramp across the exposure
        float u = float(plotted) / float(forma_pts);
        setpointattrib(0, "Cd", pt, forma_ramp(0.8 + 0.3 * u));
        plotted++;
    }
}