reas_processing · voronoi
Voronoi Diagram from Random Seeds
Every pixel on the canvas is colored with the palette color of the seed point closest to it. Lloyd relaxation (centroid-snap iterations) runs at reset to even out cell sizes and produce the canonical Reas-style smooth mosaic. step(n) jitters each seed by Gaussian noise and re-relaxes, so the cells drift, grow, and merge slowly.
Original: https://en.wikipedia.org/wiki/Voronoi_diagram
▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.
Math essence
argmin_i || (x, y) - pts_i ||^2 over all pixels (x, y). Lloyd relaxation approximates: pts_i := mean(pixel : argmin = i) using a 32x32 subsample for speed.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 320 | 80–1000 | Square canvas side length. |
num_seeds | int | 60 | 4–250 | Number of generator points. |
lloyd_steps | int | 6 | 0–30 | Lloyd relaxation rounds at reset and step. |
step_jitter | float | 6 | 0–50 | Gaussian sigma for per-step seed displacement (pixels). |
palette_mode | str | rainbow | — | rainbow, earth, grayscale, or cool color spread. |
seed | int | null | 0–999999 |
Reference
First 60 lines of reference.py. Full source:
library_external/reas_processing/voronoi/reference.py
from __future__ import annotations
from typing import ClassVar
import numpy as np
class Voronoi:
"""Voronoi diagram from jittered random seed points.
A set of *num_seeds* points is sampled inside the canvas; each pixel
is colored with the seed's color whose point it is closest to. On
each ``step`` every seed drifts a small random amount, so the cell
mosaic slowly shifts, grows, and merges. Lloyd relaxation (``n``
rounds) snaps seeds toward their cell centroids before the first
render, producing the smooth, even cells popular in Casey Reas's
generative art canon.
"""
family: ClassVar[str] = "reas_processing"
sketch: ClassVar[str] = "voronoi"
def __init__(
self,
dim: int = 320,
num_seeds: int = 60,
lloyd_steps: int = 6,
step_jitter: float = 6.0,
palette_mode: str = "rainbow",
seed: int | None = None,
) -> None:
self.dim = dim
self.num_seeds = num_seeds
self.lloyd_steps = lloyd_steps
self.step_jitter = step_jitter
self._palette_mode = palette_mode
self._seed = seed
self.reset()
def reset(self, seed: int | None = None) -> None:
if seed is not None:
self._seed = seed
self.rng = np.random.default_rng(self._seed)
self.pts = self.rng.uniform(0, self.dim, size=(self.num_seeds, 2))
self.colors = self._palette(self.num_seeds)
for _ in range(self.lloyd_steps):
self.pts = self._lloyd_step(self.pts)
def _lloyd_step(self, pts: np.ndarray) -> np.ndarray:
n = self.dim
# coarse sub-sampling 32x32 instead of n*n for speed
sub = 32
grid = np.stack(
np.meshgrid(
np.linspace(0, n - 1, sub),
np.linspace(0, n - 1, sub),
indexing="ij",
),
axis=-1,
).reshape(-1, 2) Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/reas_processing/voronoi/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from reas · processing
2-D Totalistic Cellular Automaton (Conway + variants)
reas_processing · wolframCA2D
Each cell looks at its 8 Moore neighbors and applies a totalistic rule.
Gray-Scott Reaction-Diffusion
reas_processing · grayScottRD
Two scalar species U and V diffuse on a square grid with rates Du and Dv and react with feed F and kill k.
Lindenmayer L-system + Turtle Rendering
reas_processing · lindenmayer
An axiom string is rewritten by parallel production rules for a fixed number of iterations, then interpreted by a 2-D turtle: 'F' walks forward, '+/-' turn left/right, '['/']' push/pop state.
Particle-Spring Cloth (Verlet + Hooke)
reas_processing · particleSpring
A rectangular grid of free particles is connected by Hooke's-law springs at rest length 'spacing'.
Perlin Streamlines
reas_processing · perlinStreamlines
A 2-D vector field is sampled from one or more octaves of Perlin gradient noise.
Wolfram Elementary 1-D Cellular Automaton
reas_processing · wolframCA1D
Each row of the canvas is one generation of a Wolfram elementary cellular automaton.