One Rule. Infinite Geometry.
Place a set of points on a plane. For every location in that plane, ask: which point is closest? Color each location according to its nearest point. The shapes that emerge from this deceptively simple rule — irregular, organic, never repeating — are Voronoi diagrams. They appear in giraffe skin, in the cell structure of a dragonfly wing, in the distribution of stars across a galaxy, and in the map of rainfall sensors used by meteorologists. They were formalized by mathematician Georgy Voronoi in 1908. They run in your browser in under 100 lines of JavaScript.
What makes Voronoi diagrams compelling for generative art is that they sit at a rare intersection: mathematically precise, biologically natural, and visually arresting. They do not require Perlin noise to look organic. The nearest-neighbor rule alone produces the kind of cellular irregularity that took computer graphics decades to replicate with other methods.
This article covers the mathematics, three distinct ways to compute them in JavaScript, how distance metric choice radically changes the output, and how to build the interactive demo below — a live Voronoi renderer where you control the geometry.
Where Voronoi Diagrams Actually Appear
Before touching code, it helps to understand why this structure keeps appearing in unrelated domains. The Voronoi diagram is nature's solution to a territorial problem: given a set of generators (cells, seeds, cities, stars), how does space divide itself such that every location belongs to its closest generator? Any system that operates by proximity will converge on Voronoi geometry.
Voronoi in the Wild
The Nearest-Neighbor Rule, Precisely
Given a set of n seed points P = {p₁, p₂, ..., pₙ} in a plane, the Voronoi cell V(pᵢ) for any seed pᵢ is the set of all points in the plane closer to pᵢ than to any other seed.
Each cell boundary is the perpendicular bisector between two adjacent seeds — the set of points equidistant from both. Three cells meet at a single point, called a Voronoi vertex, which is equidistant from its three corresponding seeds. That vertex is the circumcenter of the triangle formed by those three seeds — which means Voronoi diagrams and Delaunay triangulations are dual structures. Flip one and you get the other.
What changes when you swap the distance metric is the shape of "equidistant." Euclidean distance produces the circular neighborhoods we recognize from nature. Manhattan distance — the sum of horizontal and vertical steps — produces diamond-shaped neighborhoods that generate crystalline, grid-aligned cell boundaries. Chebyshev distance — the maximum of horizontal or vertical distance — produces square neighborhoods and a very different visual language.
Same seeds. Same rule. Three entirely different diagrams. This metric sensitivity is one reason Voronoi geometry is so rich for generative work.
Brute-Force Distance Field
The most direct implementation: for every pixel on the canvas, loop through every seed, find the minimum distance, and color the pixel accordingly. Complexity is O(n × w × h) — slow for large canvases and many seeds, but completely transparent in its logic and perfect for learning.
// Brute-force Voronoi — readable, not optimized function drawVoronoi(canvas, sites) { const ctx = canvas.getContext('2d'); const img = ctx.createImageData(canvas.width, canvas.height); const data = img.data; const W = canvas.width, H = canvas.height; for (let y = 0; y < H; y++) { for (let x = 0; x < W; x++) { let minDist = Infinity; let closestIdx = 0; for (let i = 0; i < sites.length; i++) { const dx = x - sites[i].x; const dy = y - sites[i].y; const d = dx*dx + dy*dy; // skip sqrt — we only need ordering if (d < minDist) { minDist = d; closestIdx = i; } } const [r, g, b] = hslToRgb(closestIdx / sites.length, 0.65, 0.75); const px = (y * W + x) * 4; data[px] = r; data[px+1] = g; data[px+2] = b; data[px+3] = 255; } } ctx.putImageData(img, 0, 0); }
Optimization tip
Notice the dx*dx + dy*dy instead of Math.sqrt(...). Because we only need to compare distances — not measure them — we can skip the square root entirely. It does not change which seed is closest; it halves the computation cost.
Drawing the Cell Edges
Flat color cells are useful, but Voronoi diagrams are most recognizable by their edges — the sharp boundaries between cells. The technique: run the brute-force pass and track not just the closest seed, but the second-closest. When their distances are very similar (within a threshold), you are near a cell boundary. Draw those pixels as edges.
// Extended inner loop — track two nearest seeds let minDist = Infinity; let secDist = Infinity; let closest = 0; for (let i = 0; i < sites.length; i++) { const d = (x-sites[i].x)**2 + (y-sites[i].y)**2; if (d < minDist) { secDist = minDist; minDist = d; closest = i; } else if (d < secDist) { secDist = d; } } // If second-closest ≈ closest, this pixel is on a boundary const isEdge = (secDist - minDist) < 2.0; if (isEdge) { data[px]=60; data[px+1]=60; data[px+2]=60; data[px+3]=200; } else { // Fill cell color as before }
Swapping the Distance Metric
The entire character of a Voronoi diagram changes when you replace the distance function. One line of code. Three completely different visual languages — and three different use cases in generative art.
// Euclidean — circular neighborhoods, organic, natural const euclidean = (ax, ay, bx, by) => Math.sqrt((ax-bx)**2 + (ay-by)**2); // Manhattan — diamond neighborhoods, crystalline, grid-aligned const manhattan = (ax, ay, bx, by) => Math.abs(ax-bx) + Math.abs(ay-by); // Chebyshev — square neighborhoods, hard-edged, architectural const chebyshev = (ax, ay, bx, by) => Math.max(Math.abs(ax-bx), Math.abs(ay-by));
EUCLIDEAN
Circular cells. Mimics natural territory — cells, skin, bubbles. The default.
MANHATTAN
Diamond cells. Urban grid feel. Named after New York city block distance.
CHEBYSHEV
Square cells. Tile-like, hard-edged. Used in chess — the king moves in Chebyshev distance.
[ VORONOI_RENDERER ]
Click to add seeds. Drag seeds to move them. Change the distance metric.
Fortune's Algorithm: From O(n²) to O(n log n)
The brute-force approach works well up to a few hundred seeds at moderate canvas sizes. Beyond that — say, thousands of seeds at high resolution — you need a smarter algorithm. Steven Fortune published his sweepline algorithm in 1987, reducing Voronoi computation from O(n²) to O(n log n).
The key insight: instead of asking "which seed is closest to this pixel?", Fortune's algorithm sweeps a line across the plane and builds the diagram incrementally. As the line moves, it maintains a beach line — a sequence of parabolic arcs, each centered on a seed, representing the boundary between "already computed" and "not yet processed" regions. Where two parabolas intersect, a Voronoi edge forms. Where three meet, a Voronoi vertex appears.
For generative art, the practical takeaway is: if you need a live Voronoi diagram with hundreds of draggable seeds at 60fps, reach for a library like d3-delaunay — which wraps the Delaunay dual (and therefore gives you Voronoi for free) using Bowyer-Watson at near-Fortune speeds. For sketches with under ~200 seeds, the pixel-loop approach above is fast enough and keeps your code fully self-contained.
What You Can Build with This
-
→
Organic texture generation
Randomize seed positions with Perlin noise over time to produce living, breathing cellular patterns. Combine with a blur pass for a convincing biological membrane.
-
→
Stippling and low-poly art
Run Voronoi, then draw only the edges. Move seeds toward the centroid of their cell (Lloyd's algorithm) repeatedly until the diagram reaches equilibrium — this is called a centroidal Voronoi tessellation and produces the visually balanced low-poly aesthetic.
-
→
Procedural terrain and maps
Assign biomes, altitude, or moisture values to seeds and fill cells accordingly. Every Civilization-style map tile is essentially Voronoi.
-
→
City and network design
Each Voronoi cell becomes a district, neighborhood, or service area. Add road networks along the edges. Add a Delaunay triangulation for connectivity.
-
→
Reactive audio visualization
Drive seed positions with FFT frequency data. Cells expand and contract with the music, making the geometry breathe in time with sound.
The Same Question, Everywhere
Voronoi diagrams keep appearing across biology, geography, physics, and design because they answer a question that nature asks constantly: given a set of centers of influence, how does space organize itself? The mathematics is simple enough to fit in a paragraph. The results are complex enough that they appear in giraffe skin without any computation at all.
For the creative coder, that simplicity is the point. You do not need to simulate biology to generate biological-looking output. You need the right rule. And "assign each pixel to its nearest seed" is one of the most powerful such rules available — especially once you start swapping out what "nearest" means.
Build the brute-force version first. Watch it render. Change the metric. Add noise to the seed positions. Connect them to audio. Move them with a physics simulation. At every step, the same underlying rule generates a different world.