Pendulum Wave
Fifteen pendulums hang in a row and are let go together. Nothing connects them: each one is cut to a length that makes it swing a set number of times a minute, the longest 51 times and each shorter one once more, up to 65. Seen from above, the row drifts out of step into snakes, splits into two alternating rows at 30 seconds, and is back in one straight line at 60 seconds, because by then every pendulum has made a whole number of swings. The bar along the foot is the 60‑second cycle; the coral bob is the longest pendulum.
About this piece
You are looking down on the row from above. The grey line across the middle is the beam the pendulums hang from, the dashed lines are the edges of the swing, and each dot is a bob, with a few fading ghosts showing where it was a moment ago. The thin line through the dots is the “snake” your eye sees; nothing physical joins them. The numbers under the row are how many full swings each pendulum makes per cycle, 51 to 65. The bar along the foot, just above the readout, is the cycle timer, 0 to 60 seconds, with ticks at a quarter, a third, a half, two thirds and three quarters, the moments the row falls into a few neat rows. The plate opens ten seconds before the row lines up, so the first thing you see is the snakes winding back into a straight line. The text under the bar gives the time into the cycle and says “back in line” or “two rows in antiphase” at those two moments. With reduced motion switched on you get one still frame, 7.5 seconds in.
The fifteen pendulums
Every number here is computed from one rule: pendulum n swings exactly n times in 60 seconds. The lengths assume g = 9.81 m/s² and are measured from the pivot to the centre of the bob:
| Pendulum | Swings per 60 s | Period (s) | Length (cm) |
|---|---|---|---|
| 1 | 51 | 1.1765 | 34.39 |
| 2 | 52 | 1.1538 | 33.08 |
| 3 | 53 | 1.1321 | 31.85 |
| 4 | 54 | 1.1111 | 30.68 |
| 5 | 55 | 1.0909 | 29.57 |
| 6 | 56 | 1.0714 | 28.53 |
| 7 | 57 | 1.0526 | 27.53 |
| 8 | 58 | 1.0345 | 26.59 |
| 9 | 59 | 1.0169 | 25.70 |
| 10 | 60 | 1.0000 | 24.85 |
| 11 | 61 | 0.9836 | 24.04 |
| 12 | 62 | 0.9677 | 23.27 |
| 13 | 63 | 0.9524 | 22.54 |
| 14 | 64 | 0.9375 | 21.84 |
| 15 | 65 | 0.9231 | 21.17 |
The longest is 34.39 cm and the shortest 21.17 cm, so the whole row spans only 13 cm of length. Pendulum 10 is the tidy one: 60 swings in 60 seconds, a period of exactly one second, at 24.85 cm. (The “seconds pendulum” of old clocks is four times as long, 99.4 cm, because there one second is half a swing.) The 60‑second cycle with 51 to 65 swings is the common lecture-demonstration choice: about one swing a second is easy to follow by eye, and every string falls between 21 and 35 cm.
The formula
A simple pendulum making small swings has period P = 2π√(L/g). To make pendulum n swing n times in a cycle of T seconds its period must be T/n, so solving for the length gives the one formula the whole plate rests on. Each bob then moves as a cosine of its own phase:
length of pendulum n L = g (T / (2π n))² angular frequency ω = √(g / L) = 2π n / T displacement at time t x = A cos(ω t) with T = 60 s and n = 51, 52, …, 65
Worked example, pendulum 1. T/n = 60/51 = 1.1765 s. Divide by 2π to get 0.18724, square it to get 0.035060, and multiply by 9.81: L = 0.3439 m, or 34.39 cm. In the code the frequency is worked out from that length, ω = √(g/L), not written down separately, so a wrong length draws a wrong pendulum, exactly as it would on a real frame.
Why they line up again, and what happens on the way
At time t pendulum n has turned through a phase of 2πn·t/T. At t = T that is 2πn, a whole number of turns for every n, so all fifteen are back at full swing on the starting side: a straight line. Between two neighbours the phase gap is 2π·t/T, the same for every pair, and it grows steadily. That steady gap is what you see as a snake. Four seconds in, neighbours are 24° apart and the row holds just under one full wave (14 × 24° = 336°). At 7.5 seconds, the reduced-motion still, they are 45° apart and the row holds one and three quarter waves.
At 30 seconds the gap is exactly 180°. Pendulums with an even swing count (52, 54, …, 64, seven of them) have made whole swings and are back on the starting side; the eight with an odd count (51, 53, …, 65) are half a swing round, on the far side. The row is two interleaved rows, swinging in antiphase. At 20 and 40 seconds the gap is 120°, so the pendulums fall into three phase groups. Every third one (51, 54, 57, 60, 63) is at full swing and the other ten sit at half swing on the far side, in two groups passing each other. At 15 and 45 seconds the gap is 90°: four groups, at the two edges and crossing the beam in each direction.
The snake is an illusion, an honest one. No energy or signal travels along the row; each pendulum keeps its own time. The wave is the same effect as a wagon wheel turning backwards on film: fifteen samples of a pattern that changes faster than the samples are spaced. Just after 30 seconds the gap is a little over 180°, and the eye pairs every second pendulum, so you see two slow snakes woven together instead of one fast, jagged one.
How it is computed
The picture is a pure function of the time into the cycle, taken from the wall clock. Each frame works out fifteen cosines, plus five more per bob for the ghosts, and redraws everything from scratch. The frame rate decides how often the picture is redrawn, never what is in it. The model lives in one block of code, used by the gallery tile, the embed and a node module that the test suite loads. The suite works out the fifteen lengths from L = g(T/(2πn))² on its own and compares them with the code’s. It checks that every phase is a whole number of turns at t = 60 s to within 10−9 radians, and that at t = 30 s every pair of neighbours is exactly half a turn apart. A planted run makes one length 1% too long. The table check fails, and so does the realignment check: that pendulum ends the cycle 104° out of line.
A 30-line version
The snippet below is the whole idea in 30 lines of HTML and plain JavaScript with no library: the fifteen lengths from the formula, each frequency from its length, the bobs seen from above, and the time into the cycle in the corner. It uses the site’s palette. With reduced motion it draws the 7.5‑second still. The test suite runs it against a stub canvas and checks that its bobs sit exactly where the plate’s do. It leaves out the beam, the snake line, the ghosts, the timer bar, sharp drawing on high-density screens (it draws in CSS pixels) and the reaction to theme changes.
Things worth changing: K = 20 gives slow, long-swinging pendulums and the same 60‑second cycle. T = 30 halves the cycle; the formula cuts every string to a quarter of its length to keep the same swing counts. N = 40 gives finer snakes, which shows how much the pattern depends on how many samples there are.
<canvas id="wave" style="position:fixed; inset:0"></canvas>
<script>
const dark = matchMedia('(prefers-color-scheme: dark)').matches;
const [ground, ink, first] = dark ? ['#0B0D12', '150,180,255', '255,120,84']
: ['#E7E2D5', '40,72,205', '190,68,28']; // the site's palette
const N = 15, K = 51, T = 60, g = 9.81; // the longest swings K times in T seconds
const w = []; // angular frequency of each pendulum
for (let i = 0; i < N; i++) {
const L = g * (T / (2 * Math.PI * (K + i))) ** 2; // metres: 0.344 down to 0.212
w.push(Math.sqrt(g / L)); // from the length alone, as a real pendulum would
}
const cv = document.getElementById('wave'), ctx = cv.getContext('2d');
const W = cv.width = innerWidth, H = cv.height = innerHeight;
const gap = W / (N + 1), A = 0.35 * H; // column spacing; the swing, seen from above
const still = matchMedia('(prefers-reduced-motion: reduce)').matches;
let t0 = null;
function frame(now) {
if (t0 === null) t0 = now;
const t = still ? T / 8 : ((now - t0) / 1000) % T; // seconds into the cycle
ctx.fillStyle = ground; ctx.fillRect(0, 0, W, H);
for (let i = 0; i < N; i++) { // all let go together, at full swing, on one side
ctx.fillStyle = `rgb(${i ? ink : first})`; ctx.beginPath();
ctx.arc(gap * (i + 1), H / 2 - A * Math.cos(w[i] * t), Math.min(12, gap / 3), 0, 2 * Math.PI);
ctx.fill();
}
ctx.fillStyle = `rgb(${ink})`; ctx.fillText(t.toFixed(1) + ' s of ' + T, 16, H - 16); // the timer
if (!still) requestAnimationFrame(frame);
}
frame(performance.now());
</script>
The plates it sits nearest
- Kuramoto Sync is the opposite experiment: oscillators with slightly different natural speeds that are coupled, and pull each other into step. Here nothing is coupled, and the row lines up only because the speeds were chosen to.
- Double Pendulum hangs a second arm on each pendulum, and a hair’s difference at release grows until no two look alike. A simple pendulum making small swings is the tame case, and that is why fifteen of them can be timed to the second.
- Moiré Interference is the same trick in space rather than time: two regular patterns slightly out of step make a large, slow pattern that neither contains.
Honest limits
Real pendulums are not quite simple-harmonic. The formula P = 2π√(L/g) is exact only for tiny swings; a swing of amplitude θ takes about (1 + θ²/16) times longer. On a real frame the bobs are usually pulled back together by one board, the same distance for all, so the short pendulums swing through bigger angles. Pull them back 5 cm and the longest swings 8.4°, running 0.13% slow, while the shortest swings 13.7°, running 0.36% slow. Over 65 swings that 0.23% difference adds up to about 52°, so a real row comes back a little ragged unless it is released gently or tuned by ear. The plate draws the ideal small-swing motion, where amplitude does not matter.
Builds need precise lengths. A 1% length error is a 0.5% period error. On pendulum 8 (58 swings) that leaves it 104° off at the 60‑second mark, plainly out of line. To stay within about 10°, a length has to be right to about 0.1%: a quarter of a millimetre on a 25 cm string.
No friction, no air. Real bobs lose amplitude and come to rest within a few minutes; these swing for ever at the same width. And the swing is drawn at the same width for every pendulum, scaled to the screen, rather than at real centimetres.
Curious how the loop and canvas fit together? Read how it works →
More from the gallery
- Plate 01 Quantum Fibonacci Golden-angle phyllotaxis blooming from the seed outward.
- Plate 02 Bitcoin Matrix A quiet rain of ₿ and hex sliding down the glass.
- Plate 03 Cosmic Circles Soft orbs drifting through slow orbital rounds.
- Plate 04 Spiral Waves Archimedean arms turning, so the bands seem to stream inward.
- Plate 05 Particle Burst A continuous bloom of particles from the core.
- Plate 06 Geometric Flow Hexagons orbiting in harmonic rotation.