Quantum Fibonacci
Golden-angle phyllotaxis: 320 seeds turning slowly and breathing, packed like a sunflower head.
About this piece
Quantum Fibonacci draws a sunflower head of 320 seeds, one soft dot per seed, and nothing else. Seed number n is placed by two rules. Its direction is the previous seed’s direction turned by the golden angle, 137.5078° (π(3 − √5) radians), and its distance from the centre is 0.031 of the frame’s short edge times the square root of n. That is the whole recipe; every dot is recomputed from those two rules on every frame, so there is no trail and no randomness, and the head looks the same on every visit.
Three slow motions sit on top of it. The whole head turns clockwise, 0.25 radians per unit of animation time; the clock advances 0.03 per frame, so one full turn takes about 838 frames, about 14 seconds on a 60 Hz screen. Each dot breathes: its size is multiplied by 0.6 + 0.4 sin(1.5t + 0.28n), which swings between a fifth of full size and full size about every 2.3 seconds and never reaches zero, so no seed ever disappears. Because each seed is 0.28 radians out of step with the one placed before it, the swelling ripples through the head instead of the whole disc beating at once. And the dots grow toward the rim, the outermost about 3.2 times the size of the innermost. Every 9th seed (36 of the 320) takes the site’s coral ink; the rest are cobalt, and both inks switch with the light or dark theme.
“Quantum Fibonacci” is the piece’s title and nothing more: nothing quantum is simulated here, and the motion is plain trigonometry. The name is kept because it is how the catalogue has always listed this plate.
Why this is the sunflower model
These two rules are H. Vogel’s 1979 model of a sunflower head, published as “A better way to construct the sunflower head” in Mathematical Biosciences (vol. 44, pp. 179–189). In Vogel’s form, floret n sits at
r = c √n, θ = n × 137.508°
where c is a scaling constant; here c is 0.031 of the short edge. The square root is what keeps the head evenly dense. The area inside radius c√n is πc²n, so it grows by exactly the same amount, πc², for every seed added: each seed gets an equal share of area, and the curve through successive seeds (Fermat’s spiral) crosses equal-area rings in equal turns. A worked case: the first 80 seeds fill the circle of half the head’s radius, and that circle holds a quarter of the head’s area and a quarter of its 320 seeds. With a short edge of 600 pixels, each seed’s share is about 1,090 square pixels, a patch roughly 33 pixels across, at the centre and at the rim alike.
The angle is what keeps the seeds from lining up. Turn by a simple fraction of a circle instead and the seeds fall into straight spokes: at 135°, which is exactly 3/8 of a turn, seed 8 lands in seed 0’s direction, seed 9 in seed 1’s, and all 320 seeds end up on just 8 rays with bare wedges between them. The golden angle is 1/φ² of a turn, where φ is the golden ratio, and φ is the extreme case of a number that fractions approximate badly: the best fractions for it are ratios of consecutive Fibonacci numbers, and they close in on it unusually slowly. So no seed ever sits exactly behind an earlier one, and the gaps keep being filled. Analysis of the pattern shows it is highly sensitive to this angle, with the Fibonacci angle giving the best packing density.
What to look for
Look for the parastichies — the word botanists use for the spiral rows of florets in a sunflower head, or of scales on a pine cone. Here they are the clockwise and counter-clockwise arcs your eye traces from each dot to its nearest neighbours. Their counts are not folklore; they can be read off the plate’s own geometry. For each of the outer 40 seeds (numbers 280 to 319), the nearest neighbours are always seeds 34 and 55 numbers away. Seeds 34 apart lie on one shared arc, so the rim shows 34 arcs winding one way and 55 the other: 34 steps of 137.5078° come to 4.7° short of a whole number of turns, and 55 steps overshoot by 2.9°, so the two families lean in opposite directions.
The numbers drop as you move in. Seeds k apart in the sequence differ in radius by about ck/(2√n), so near the centre only seeds a few steps back are close enough in radius to be neighbours, while further out a seed 34 or 55 steps back is still close, and whichever of those also lands closest in direction wins. Seeds 80 to 139 meet their neighbours 21 or 34 apart, seeds 40 to 79 meet them 13 or 21 apart, and seeds 20 to 39 meet them 8 or 13 apart. So the familiar “8 one way, 13 the other” is true only near the centre of this head; at the rim, where the eye mostly looks, it is 34 and 55.
Honest limits
The head is bigger than the frame’s short side. The last seed sits 0.031 × √319, about 0.55 of the short edge, from the centre, so on a landscape stage the outer seeds from about number 260 onward are cut off at the top and bottom, and on a phone held upright they are cut off at the sides.
The motion is counted in frames, not seconds. The 14-second turn and the 2.3-second breath hold on a 60 Hz screen; a 120 Hz display runs twice as fast, and a busy machine that drops frames runs slower. Under prefers-reduced-motion the plate draws one still frame and does not turn or breathe.
This is the ideal sunflower, not a botanical simulation. The spirals of a mature head take this shape ideally, when all the florets are the same size; Vogel’s model assumes that and an exact angle, and this plate adds nothing about how a real head grows. Its dots also vary in size for looks while their spacing stays the model’s.
Draw your own
Vogel’s model is two lines of arithmetic: seed n is turned n × 137.508° from the first and set c √n from the centre. The golden angle exactly is 360(2 − φ) ≈ 137.50776°, with φ = (1 + √5)/2. Why it packs without gaps: the square root hands every seed the same patch of area, and because no number of golden-angle steps ever adds up to a whole number of turns, no seed lands behind an earlier one, so the seeds never stack into spokes with bare wedges between them.
The snippet below is that model in 24 lines of HTML and plain JavaScript, with no library. With c = 12 px, the last of 320 seeds sits 12 × √319 ≈ 214 px out, inside a 480 px canvas, and each seed’s share of the disc is π × 12² ≈ 452 square pixels, a patch about 21 px across. The dots grow from a 3 px radius at the centre to about 8 px at the rim, so roughly 4 px of ground stays visible between neighbours everywhere. Every 9th seed takes the coral ink, as on the plate, and the cobalt, coral and ground are the ones this page’s animation reads from the site palette, light or dark to match your device. Save it as an .html file and open it.
<canvas id="sunflower" width="480" height="480"></canvas>
<script>
const dark = matchMedia('(prefers-color-scheme: dark)').matches; // follow the OS theme
const [bg, cobalt, coral] = dark ? ['#0B0D12', '150,180,255', '255,120,84']
: ['#E7E2D5', '40,72,205', '190,68,28'];
document.body.style.background = bg;
const ctx = document.getElementById('sunflower').getContext('2d');
const golden = 137.50776405; // degrees: 360 * (2 - phi), with phi = (1 + sqrt(5)) / 2
const c = 12, N = 320; // r = c * sqrt(n): each new seed adds PI*c*c = 452 px^2 of disc
const still = matchMedia('(prefers-reduced-motion: reduce)').matches;
let shown = still ? N : 0;
function frame() {
ctx.clearRect(0, 0, 480, 480);
for (let n = 0; n < shown && n < N; n++) {
const a = n * golden * Math.PI / 180, r = c * Math.sqrt(n); // Vogel 1979
ctx.fillStyle = 'rgba(' + (n % 9 ? cobalt : coral) + ',0.9)'; // every 9th seed coral
ctx.beginPath(); ctx.arc(240 + r * Math.cos(a), 240 + r * Math.sin(a), 3 + r / 40, 0, 2 * Math.PI);
ctx.fill();
}
shown = shown > N + 90 ? 0 : shown + 1; // one new seed a frame, hold 1.5 s, start over
if (!still) requestAnimationFrame(frame);
}
frame();
</script>
The motion is the model run forward: one new seed per frame, so the head fills in 320 frames, about 5.3 seconds at 60 frames a second, holds for 90 frames (1.5 seconds) and starts again. Under prefers-reduced-motion it draws all 320 seeds at once and stops.
Where to take it: set golden to 137.0, half a degree off, and the seeds bunch into curved arms with bare ground between them; at 135, exactly 3/8 of a turn, they fall onto the 8 straight spokes described above. Raise N to 1000 and lower c to 6.8 and three times as many seeds fit in the same disc, the last one about 215 px out; shrink the dot radius to 1.5 + r / 60 as well, or the rim dots, now only about 12 px apart, overlap. What the snippet does not do: its speed is counted in frames, so it runs twice as fast on a 120 Hz screen; it reads your light or dark setting once, when the page loads; and it draws at 480 CSS pixels without scaling for high-density screens, so the dots are slightly soft on a phone or a Retina display.
Sources: Fermat’s spiral (Vogel’s model and its 1979 citation), Golden angle (its exact value, 360(2 − φ), used in the snippet), Golden ratio and Parastichy on Wikipedia, read 2026-10-01. Every count and size above is computed from the animation’s own code.
Curious how the loop and canvas fit together? Read how it works →
More from the gallery
- 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.
- Plate 07 Color Symphony Layered sine waves scrolling in phase.