Visualizations
004 / 500

004 · Generative art

Roman Mosaic

Thousands of tesserae laid in rows that follow every outline, as a Roman mosaicist would.

This follows Alejo Hausner's simulated decorative mosaics. The figure and its guilloche border are painted as a label map, and two exact Euclidean distance transforms are taken from the label edges: one colors each region in rows that follow its outline, from a dark outline row inward, and one, which also counts the panel border and any guide curves, gives the direction field whose gradient is the edge normal (smoothed as four times the angle, since a square repeats every quarter turn). Seeds are dropped along the iso-contours of that distance, nearest rows first, then relaxed as a centroidal Voronoi tessellation under an oriented max-norm, where each cell only takes grid points of its own region. Each tessera is cut to its cell's extent in its own frame, so stones shrink where they meet an edge, and they are laid outlines first over the red sinopia underdrawing.

Try it. Paint a curve anywhere to bend the direction field: new rows grow parallel to it and the tiles flow into place. Choose a dolphin, fish, partridge or rosette, switch between fine, medium and coarse tesserae, and clear your guides to let the rows settle back.

  • Centroidal Voronoi tessellation
  • Oriented L-infinity metric
  • Euclidean distance transform
  • Iso-contour seeding
  • Label-map regions

View the source · one module, plus a small shared runtime for sizing, the animation loop and input

Build your own

Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.

Build a Roman floor mosaic generator with JavaScript and the HTML canvas element, where square tiles line up in rows that follow the outlines of a figure. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.

Start simple:
- Make a canvas that fills the window, stays sharp on high-DPI screens (scale by devicePixelRatio), and resizes with the window.
- Draw a simple figure (a fish made of an ellipse and a triangle tail) in flat colors onto a hidden canvas the same size, and read it back with getImageData. That is the picture the mosaic will copy.
- Find its edges (pixels whose color differs from a neighbor) and compute, for every pixel of a coarse grid, the distance to the nearest edge. A simple two-pass chamfer distance transform is fine.
- Place tiles in rows: for row k, take the grid points whose distance is close to (k + 0.5) times the tile size, and accept a point only if no tile already sits within 0.9 tile sizes of it.
- Turn each tile to match the edge: the gradient of the distance field points away from the nearest edge, so use its angle as the tile's rotation. Draw each tile as a slightly smaller rotated square in the picture's color at its center, on a light gray grout background.

Once that works, make it beautiful:
- Give the stones a Roman palette (white marble, ochre, terracotta, slate, black) with a little random variation per tile, and a bevel: a light stroke on the edges that face the upper left and a dark one on the others.
- Shade the figure in bands that follow its outline: a dark first row, then lighter rows inward.
- Animate the laying, closest rows to the edges first.

Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as relaxing the tiles with a centroidal Voronoi tessellation, letting the user paint guide curves that the rows follow, or a twisted guilloche border.
PreviousAuroraCurtains of oxygen and nitrogen light on tilted field lines, mirrored in a lake. NextRubik's CubeA 3D cube that scrambles itself and then solves itself, layer by layer.

Related visualizations

  • Voronoi MosaicMath Drifting seeds divide the plane into a living stained-glass mosaic.
  • Tessellation MorphMath Drag one edge of an Escher-style creature and every copy reshapes while still tiling.
  • Floral OrnamentGenerative art Scrolls, acanthus leaves and flowers grow to fill any frame, like an engraver's panel.
  • Multiscale TruchetGenerative art Truchet tiles at five scales lock together seamlessly, flipping color at each level.
  • Zen GardenGenerative art Raked gravel in low morning sun, its furrows flowing around mossy stones.
  • Op ArtGenerative art Riley and Vasarely style compositions that ripple, bulge and vibrate.
  • Topographic SurveyGenerative art Eroded terrain printed as a survey sheet with labeled contours, streams and hillshade.
  • Haeckel PlatesGenerative art An endless folio of generative radiolarians, diatoms and medusae in lithograph ink.
  • Penrose PentagridMath Five grids of parallel lines dualize into a living Penrose tiling of stained glass.

Use ← and → to move between demos. While the canvas has focus, keys go to the demo instead.

← More from Emergent Mind Labs