Signal and Sensation

Chladni Figures

Sand on a vibrating plate draws the shape of a standing wave. Sweep for a resonance and watch it assemble.

Open fullscreen →

What it is

A square plate driven by a sine tone, with thirty thousand grains of sand on it. Sweep the pointer to change the frequency.

Most of the time nothing happens and the sand just shivers. Land on one of the plate’s resonances and the grains rush into a figure.

How it works

Nothing here draws a pattern. The pattern is where the maths happens to be zero.

The plate’s displacement is cos(nπx)cos(mπy) − cos(mπx)cos(nπy). That difference of two products is the whole trick. It’s antisymmetric about the diagonal, so the diagonal is always a nodal line, and the rest of the figure follows from the two integers.

Sand sitting where the plate is moving gets thrown off, sand sitting where it’s still stays put. So each grain steps down the gradient of displacement squared and gets shaken in proportion to how much the plate moves underneath it.

Two details make it feel physical rather than decorative. The gradient is normalised before stepping, because near an antinode it’s enormous and would fling grains clean across the plate in a single frame. And resonances are discrete, so between them the drive gets no lock, every grain is agitated and nothing gathers at all. Tuning into a mode is the whole pleasure of it.

What surprised me

Drawing thirty thousand grains as thirty thousand fillRect calls doesn’t work. Writing them straight into an ImageData buffer through a Uint32Array view does, easily, at sixty frames a second.

But the buffer needs two passes, not one. The first tallies how many grains landed on each pixel, the second colours each pixel by that tally.

Without the tally every grain is equally bright, and a nodal line with two hundred grains piled on it looks exactly like scattered sand. The pile-up is the picture.

What I would do next

Two tones at once, and the interference between their figures.