Sketch · 2026-06-05
Marching squares.
A grid of numbers, a threshold, sixteen cases. For every cell of the grid you look at the four corner values, mark each one as above or below the threshold, and pick the contour fragment that matches the resulting four-bit code. Glue the fragments together and you have an isoline.
Drag inside the stage to sweep the threshold.
The algorithm
Label the four corners of a cell with one bit each: 1 if the value there is above the threshold, 0 if below. The four bits form a number from 0 to 15 — fifteen non-trivial cases, two of them ambiguous saddles. Each case maps to one or two line segments that cross the cell edges. The crossing points come from linear interpolation between the two corner values.
// corners labelled TL, TR, BR, BL (clockwise from top-left) const code = (a > t) << 3 | (b > t) << 2 | (c > t) << 1 | (d > t); // where on edge TL-TR does the contour cross? const ux = (t - a) / (b - a); // then look up the segment list for code 0..15
The field underneath is the sum of six drifting two-dimensional Gaussians. Each blob has a centre that orbits slowly and a width that breathes. The value at any point is the sum of the contributions, so the contours bend around the blobs and merge as they overlap.
The sixteen cases
Cases 0 and 15 are empty, the corners agree. Cases 1, 2, 4 and 8 cut one corner. Cases 3, 6, 9 and 12 cut across an edge. Cases 5 and 10 are the saddle pairs; the segments here can be wired two ways and the choice matters for connectivity. The rest are mirror images.
Source
Lorensen, W. E. and Cline, H. E., "Marching Cubes: A High Resolution 3D Surface Construction Algorithm" (SIGGRAPH 1987). The two-dimensional version implemented here is the obvious projection; credit for it tends to be diffuse, though the algorithm is usually attributed to the same paper for both.