30 drifting seeds carve the canvas by nearest-neighbor ownership. Click to add seeds, drag to push, R to reset.
A soap bubble film between two parallel planes divides into cells where every wall sits equidistant from two seed points. A giraffe's coat does the same thing. So does the structural lattice inside a bird's skull bone, and the recrystallized grain pattern in cooled steel. The geometry that shows up in these places has a name: Voronoi tessellation. Each cell owns every point in space closer to its seed than to any other.
Descartes sketched the idea in 1644 while speculating about the structure of matter near the sun. Dirichlet formalized it in 1850 for quadratic forms in two and three dimensions. Georgy Voronoy generalized it to n-dimensional space in 1907–1908, which is where the name stuck. But the clearest early demonstration that Voronoi diagrams describe something real came before any of them published the formal definition: in 1854, John Snow mapped cholera deaths in London and drew boundaries around the Soho water pumps. Each boundary was an approximate equidistant line between pumps. The contaminated Broad Street pump sat at the center of the densest cluster. Snow didn't know he was drawing a Voronoi diagram. He was just trying to identify the source.
The algorithm here is brute force: for every pixel in a downsampled buffer, find the closest seed by squared Euclidean distance and paint that pixel the seed's color. No Fortune's sweep line, no half-plane intersections, no O(n log n) cleverness. Just a triple nested loop:
for (let py = 0; py < bH; py++) {
const wy = py * SCALE;
for (let px = 0; px < bW; px++) {
const wx = px * SCALE;
let minD = Infinity, closest = 0;
for (let i = 0; i < n; i++) {
const dx = wx - seeds[i].x;
const dy = wy - seeds[i].y;
const d = dx * dx + dy * dy;
if (d < minD) { minD = d; closest = i; }
}
// paint pixel with seeds[closest] color
}
}
The buffer renders at 1/4 resolution (SCALE = 4) and gets scaled back up with imageSmoothingEnabled = false to preserve the pixelated cell edges. For 30 seeds at a 400×225 buffer, this is around 2.7 million distance comparisons per frame — fast enough at 60 fps, clearly not the approach you'd take with 500 seeds. Fortune's algorithm would finish the diagram in a single sweep regardless of seed count. The brute force version only survives because small seed counts and the quarter-resolution buffer keep the constant small.
What's worth noticing in the visualization is cell size variation. Seeds near the center of a dense cluster own tiny slivers; seeds near the edge own large open regions. The area a cell covers is not a property of the seed — it's an accident of where the neighbors happened to land. Every cell is locally correct (it owns exactly the points closest to its seed) and globally sensitive to the whole configuration. Move one seed and every cell boundary in the diagram shifts.
← Back to showcase