Click to regenerate. Press M to cycle through arc, triangle, and diagonal rendering modes.
In 1704, Sébastien Truchet published "Mémoire sur les combinaisons" in the Histoire de l'Académie Royale des Sciences. Truchet was a Dominican priest, a hydraulic engineer, a typographer who cut the typefaces for Louis XIV's Imprimerie Royale. The paper described something simpler than any of those trades: a square tile divided along one diagonal into two colored triangles. Four rotations of a single tile. Two tiles placed edge to edge. Truchet enumerated 64 pairwise combinations and engraved plates of the resulting patterns, documenting what happens when a trivially simple local rule produces nontrivial global structure.
The paper slept for nearly three centuries. Cyril Stanley Smith, a metallurgist and historian of science at MIT, rediscovered it in 1987 and published "The Tiling Patterns of Sebastien Truchet and the Topology of Structural Hierarchy" in Leonardo. Smith recognized the tilings as an early exercise in combinatorial symmetry and connected them to Islamic geometric art, Celtic knotwork, and the field/ground reversals studied in crystallography. He included Pauline Boucher's English translation of Truchet's text, rescuing it from archival obscurity.
The arc variant, the one most people associate with Truchet tiles today, came later. It replaces the diagonal split with two quarter-circle arcs connecting adjacent edge midpoints. Each tile still has exactly two orientations. Placed randomly, the arcs form continuous meandering curves that weave across the grid without terminating. The visual complexity emerges entirely from the binary coin flip at each cell.
function drawArcTile(x, y, s, flip) {
ctx.lineWidth = s * 0.12;
ctx.lineCap = 'round';
ctx.strokeStyle = palette[0];
if (flip) {
ctx.beginPath();
ctx.arc(x + s, y, s / 2, Math.PI * 0.5, Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(x, y + s, s / 2, -Math.PI * 0.5, 0);
ctx.stroke();
} else {
ctx.beginPath();
ctx.arc(x, y, s / 2, 0, Math.PI * 0.5);
ctx.stroke();
ctx.beginPath();
ctx.arc(x + s, y + s, s / 2, Math.PI, Math.PI * 1.5);
ctx.stroke();
}
}
Each flip value chooses which pair of corners the arcs connect. One orientation links top-left to bottom-right; the other links top-right to bottom-left. The arcs meet at edge midpoints, so neighboring tiles always connect smoothly regardless of orientation. The grid is stored as a binary matrix, one random bit per cell, and the entire visual output follows from iterating that matrix with a single drawing function.
function generate() {
pickPalette();
const cols = Math.ceil(W / tileSize) + 1;
const rows = Math.ceil(H / tileSize) + 1;
grid = [];
for (let r = 0; r < rows; r++) {
const row = [];
for (let c = 0; c < cols; c++) {
row.push(Math.random() < 0.5 ? 0 : 1);
}
grid.push(row);
}
draw();
}
The animation loop flips one random tile every 120 milliseconds, so the pattern drifts without ever being regenerated wholesale. Curves merge and split as the visual field reorganizes through single-bit mutations. Truchet never saw this particular variant, and he could not have animated it, but the logic running underneath is exactly what he catalogued in 1704: local orientation choices propagating into global pattern.
Truchet Tiles
Three rendering modes (arcs, triangles, diagonal), random palette selection, slow mutation animation. Click to regenerate, M to cycle styles.
View artifact →