Fibonacci Spiral: How to Create Beautiful Golden Ratio Art With Code
The Fibonacci sequence — 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89... — is one of those rare mathematical ideas that shows up everywhere. In the spiral of a nautilus shell. In the arrangement of seeds in a sunflower head. In the branching of trees, the curl of ocean waves, and the arms of spiral galaxies. The ratio between consecutive Fibonacci numbers converges to the golden ratio φ (phi) ≈ 1.6180339887, and the spirals these numbers produce are among the most aesthetically pleasing curves in mathematics.
What makes Fibonacci spirals special isn't just their mathematical elegance — it's that nature independently discovered them billions of years ago. Phyllotaxis (the arrangement of leaves on a stem) uses the golden angle (≈ 137.5°) because it's the most irrational angle — it produces the most uniform distribution of seeds, leaves, or florets. Evolution optimized for the golden ratio long before mathematicians named it.
In this guide, we'll build 8 Fibonacci and golden ratio visualizations from scratch using JavaScript and the HTML Canvas API. No libraries. No frameworks. Just numbers and pixels.
1. The golden spiral — quarter-circle arcs
The classic golden spiral is constructed by drawing quarter-circle arcs inside a sequence of golden rectangles. Each rectangle is φ times wider than it is tall, and when you cut a square from one side, the remaining piece is another golden rectangle. The arc in each square connects to form a smooth, continuously expanding spiral.
We approximate this using Fibonacci numbers for the square sizes, drawing arcs that rotate 90° at each step:
const canvas = document.createElement('canvas');
canvas.width = 800; canvas.height = 600;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
// Generate Fibonacci numbers
const fib = [1, 1];
for (let i = 2; i < 14; i++) fib.push(fib[i-1] + fib[i-2]);
const scale = 1.2;
let x = 380, y = 260;
let angle = 0;
ctx.fillStyle = '#0a0a0a';
ctx.fillRect(0, 0, 800, 600);
// Draw golden rectangles and spiral arcs
for (let i = 0; i < 12; i++) {
const size = fib[i] * scale;
// Draw square
ctx.save();
ctx.translate(x, y);
ctx.rotate(angle);
ctx.strokeStyle = `hsla(${i * 30}, 60%, 50%, 0.4)`;
ctx.lineWidth = 1;
ctx.strokeRect(0, 0, size, size);
// Draw quarter-circle arc
ctx.strokeStyle = `hsl(${i * 30}, 70%, 60%)`;
ctx.lineWidth = 2.5;
ctx.beginPath();
ctx.arc(size, size, size, Math.PI, Math.PI * 1.5);
ctx.stroke();
ctx.restore();
// Move to next square position
const cos = Math.cos(angle);
const sin = Math.sin(angle);
switch (i % 4) {
case 0: x += cos * size; y += sin * size; break;
case 1: x -= sin * size; y += cos * size; break;
case 2: x -= cos * size; y -= sin * size; break;
case 3: x += sin * size; y -= cos * size; break;
}
angle -= Math.PI / 2;
}
// Label
ctx.fillStyle = '#ffffff';
ctx.font = '14px monospace';
ctx.fillText('Golden Spiral — Fibonacci Rectangle Subdivision', 20, 30);
The spiral expands by a factor of φ with each quarter turn. This self-similar growth — looking the same at every scale — is why the golden spiral appears so often in nature. A nautilus shell grows by adding material at a constant angular rate, producing exactly this curve.
2. Fibonacci sequence visualizer — the growing bars
Before diving into spirals, let's visualize the sequence itself. Each bar represents a Fibonacci number, and we animate their growth to show how quickly the sequence explodes (exponential growth at rate φ):
const canvas = document.createElement('canvas');
canvas.width = 800; canvas.height = 600;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
const fib = [1, 1];
for (let i = 2; i < 20; i++) fib.push(fib[i-1] + fib[i-2]);
const maxVal = fib[fib.length - 1];
let progress = 0;
function draw() {
ctx.fillStyle = '#0a0a0a';
ctx.fillRect(0, 0, 800, 600);
const barW = 36;
const gap = 4;
const startX = 20;
const baseY = 560;
const numBars = Math.min(Math.floor(progress), fib.length);
const fractional = progress - Math.floor(progress);
for (let i = 0; i < numBars; i++) {
const maxH = 500;
let h = (fib[i] / maxVal) * maxH;
// Log scale for visibility of small values
h = (Math.log(fib[i] + 1) / Math.log(maxVal + 1)) * maxH;
const animH = i === numBars - 1 && fractional < 1
? h * easeOut(fractional) : h;
const hue = (i / fib.length) * 280;
ctx.fillStyle = `hsl(${hue}, 65%, 55%)`;
ctx.fillRect(startX + i * (barW + gap), baseY - animH, barW, animH);
// Number label
ctx.fillStyle = '#ffffff';
ctx.font = '11px monospace';
ctx.textAlign = 'center';
ctx.fillText(
fib[i].toLocaleString(),
startX + i * (barW + gap) + barW / 2,
baseY - animH - 8
);
}
// Ratio labels
ctx.fillStyle = 'rgba(255,255,255,0.5)';
ctx.font = '10px monospace';
for (let i = 2; i < numBars; i++) {
const ratio = (fib[i] / fib[i-1]).toFixed(4);
ctx.fillText(
`φ≈${ratio}`,
startX + i * (barW + gap) + barW / 2,
baseY + 16
);
}
ctx.fillStyle = '#ffffff';
ctx.font = '14px monospace';
ctx.textAlign = 'left';
ctx.fillText(`Fibonacci Sequence — ratio → φ = 1.6180339887...`, 20, 30);
if (progress < fib.length) {
progress += 0.03;
requestAnimationFrame(draw);
}
}
function easeOut(t) { return 1 - Math.pow(1 - t, 3); }
draw();
Watch the ratio labels converge to φ. By the 10th term, the ratio is already 1.6176... — within 0.03% of the true golden ratio. This rapid convergence is why Fibonacci numbers are such a good practical approximation of the golden ratio in nature: you don't need infinite terms to get "close enough" for biology.
3. Phyllotaxis — the sunflower spiral
This is where Fibonacci meets nature most dramatically. In a sunflower head, seeds are arranged in a spiral pattern where each seed is placed at the golden angle (≈ 137.507764°) from the previous one. This angle is 360° / φ² — and it produces the most uniform packing possible. Any other angle creates visible gaps or lines; the golden angle fills space optimally.
The result: you can count the spirals in both directions and you'll always get consecutive Fibonacci numbers (13 and 21, or 21 and 34, or 34 and 55).
const canvas = document.createElement('canvas');
canvas.width = 800; canvas.height = 600;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
const goldenAngle = Math.PI * (3 - Math.sqrt(5)); // ≈ 137.5° in radians
const cx = 400, cy = 300;
let n = 0;
const maxN = 800;
function draw() {
ctx.fillStyle = 'rgba(10, 10, 10, 0.05)';
ctx.fillRect(0, 0, 800, 600);
// Draw batch of seeds
const batch = Math.min(n + 8, maxN);
for (let i = n; i < batch; i++) {
const angle = i * goldenAngle;
const r = Math.sqrt(i) * 8;
const x = cx + r * Math.cos(angle);
const y = cy + r * Math.sin(angle);
const size = 3 + (i / maxN) * 3;
const hue = (i * goldenAngle * 180 / Math.PI) % 360;
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI * 2);
ctx.fillStyle = `hsl(${hue}, 70%, 55%)`;
ctx.fill();
}
n = batch;
// Labels
ctx.fillStyle = '#ffffff';
ctx.font = '14px monospace';
ctx.fillText(`Phyllotaxis — Golden Angle ≈ 137.5° — ${n} seeds`, 20, 30);
ctx.font = '11px monospace';
ctx.fillStyle = 'rgba(255,255,255,0.6)';
ctx.fillText('Count the spirals: 13, 21, 34, 55 — all Fibonacci numbers', 20, 52);
if (n < maxN) requestAnimationFrame(draw);
}
draw();
The placement formula is beautifully simple: seed i goes at angle i × golden_angle and distance √i × spacing. The square root gives equal area per seed (since area grows as r²). This single formula, with a single irrational constant, produces the entire complex spiral pattern. Nature's algorithm is one line of code.
4. Golden rectangle subdivision — recursive tiling
A golden rectangle has an aspect ratio of φ:1. When you cut a square from one end, the remaining rectangle is also a golden rectangle, just smaller. You can repeat this process infinitely, creating a fractal tiling where every piece has the same proportions as the whole.
We animate this recursive subdivision, coloring each square based on its depth:
const canvas = document.createElement('canvas');
canvas.width = 800; canvas.height = 600;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
const phi = (1 + Math.sqrt(5)) / 2;
let maxDepth = 0;
function subdivide(x, y, w, h, depth, horizontal) {
if (depth > maxDepth || w < 2 || h < 2) return;
const hue = (depth * 35 + 200) % 360;
ctx.fillStyle = `hsla(${hue}, 55%, ${45 + depth * 3}%, 0.8)`;
ctx.strokeStyle = `hsl(${hue}, 40%, 30%)`;
ctx.lineWidth = 2;
if (horizontal) {
const sq = Math.min(w, h);
ctx.fillRect(x, y, sq, sq);
ctx.strokeRect(x, y, sq, sq);
// Draw arc
ctx.beginPath();
ctx.strokeStyle = `hsla(${hue}, 70%, 70%, 0.8)`;
ctx.lineWidth = 2.5;
const startAngle = Math.PI * 0.5 * depth;
ctx.arc(
x + (depth % 4 < 2 ? sq : 0),
y + (depth % 4 === 0 || depth % 4 === 3 ? sq : 0),
sq, startAngle, startAngle + Math.PI * 0.5
);
ctx.stroke();
subdivide(x + sq, y, w - sq, h, depth + 1, false);
} else {
const sq = Math.min(w, h);
ctx.fillRect(x, y, sq, sq);
ctx.strokeRect(x, y, sq, sq);
ctx.beginPath();
ctx.strokeStyle = `hsla(${hue}, 70%, 70%, 0.8)`;
ctx.lineWidth = 2.5;
const startAngle = Math.PI * 0.5 * depth;
ctx.arc(
x + (depth % 4 === 1 || depth % 4 === 2 ? sq : 0),
y + (depth % 4 < 2 ? sq : 0),
sq, startAngle, startAngle + Math.PI * 0.5
);
ctx.stroke();
subdivide(x, y + sq, w, h - sq, depth + 1, true);
}
}
function animate() {
ctx.fillStyle = '#0a0a0a';
ctx.fillRect(0, 0, 800, 600);
const w = 560;
const h = w / phi;
const ox = (800 - w) / 2;
const oy = (600 - h) / 2;
ctx.strokeStyle = 'rgba(255,255,255,0.3)';
ctx.lineWidth = 1;
ctx.strokeRect(ox, oy, w, h);
subdivide(ox, oy, w, h, 0, true);
ctx.fillStyle = '#ffffff';
ctx.font = '14px monospace';
ctx.fillText(`Golden Rectangle Subdivision — depth: ${maxDepth}`, 20, 30);
ctx.font = '11px monospace';
ctx.fillStyle = 'rgba(255,255,255,0.6)';
ctx.fillText(`φ = (1 + √5) / 2 ≈ ${phi.toFixed(10)}`, 20, 52);
if (maxDepth < 12) {
maxDepth++;
setTimeout(animate, 600);
}
}
animate();
Each level of subdivision zooms into a self-similar copy of the whole. The golden rectangle is the only rectangle where removing a square leaves a similar rectangle. This uniqueness is why φ appears in so many optimization problems — it's the fixed point of the "cut a square and recurse" operation.
5. Fibonacci word fractal — the string theory of geometry
The Fibonacci word is a binary string built like the Fibonacci sequence, but with strings instead of numbers. Start with "1" and "0", then concatenate: "01", "010", "01001", "01001010"... The n-th Fibonacci word has length equal to the n-th Fibonacci number.
To draw the fractal: walk along the string. For each character, move forward one step. At each "0", turn left if its position is even, right if odd. The result is a fractal curve with remarkable self-similar structure:
const canvas = document.createElement('canvas');
canvas.width = 800; canvas.height = 600;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
// Generate Fibonacci word
let a = '1', b = '0';
for (let i = 0; i < 20; i++) {
const temp = b;
b = b + a;
a = temp;
}
const word = b.slice(0, 6000);
ctx.fillStyle = '#0a0a0a';
ctx.fillRect(0, 0, 800, 600);
let x = 100, y = 450;
let dir = 0; // 0=right, 1=up, 2=left, 3=down
const step = 3;
const dx = [1, 0, -1, 0];
const dy = [0, -1, 0, 1];
ctx.beginPath();
ctx.moveTo(x, y);
for (let i = 0; i < word.length; i++) {
x += dx[dir] * step;
y += dy[dir] * step;
const hue = (i / word.length) * 300;
ctx.strokeStyle = `hsl(${hue}, 65%, 55%)`;
ctx.lineWidth = 1.5;
ctx.lineTo(x, y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(x, y);
if (word[i] === '0') {
dir = (dir + (i % 2 === 0 ? 1 : 3)) % 4;
}
}
ctx.fillStyle = '#ffffff';
ctx.font = '14px monospace';
ctx.fillText(`Fibonacci Word Fractal — ${word.length} steps`, 20, 30);
ctx.font = '11px monospace';
ctx.fillStyle = 'rgba(255,255,255,0.6)';
ctx.fillText('Turn on "0" (left if even index, right if odd). Walk straight on "1".', 20, 52);
The Fibonacci word fractal tiles the plane in a pattern related to Penrose tilings. Both use the golden ratio as their fundamental scaling constant. The curve never crosses itself and fills a region whose shape echoes the golden rectangle — self-similarity at the level of the generating rule itself.
6. Fibonacci spiral galaxy — particle simulation
Spiral galaxies often have arms that follow logarithmic spirals — the same family of curves as the golden spiral. We simulate a galaxy using particles placed along multiple spiral arms, with density following an exponential decay from the center:
const canvas = document.createElement('canvas');
canvas.width = 800; canvas.height = 600;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
const cx = 400, cy = 300;
const numArms = 2;
const numParticles = 8000;
const particles = [];
for (let i = 0; i < numParticles; i++) {
const arm = i % numArms;
const armAngle = (arm / numArms) * Math.PI * 2;
// Distance from center (exponential distribution)
const t = Math.random();
const dist = 20 + Math.pow(t, 0.5) * 250;
// Spiral: angle increases logarithmically with distance
// Using golden ratio as the growth factor
const phi = (1 + Math.sqrt(5)) / 2;
const spiralAngle = armAngle + Math.log(dist / 20) * phi * 1.2;
// Add scatter (more at greater distances)
const scatter = (0.3 + t * 0.7) * 30 * (Math.random() - 0.5);
const scatterY = (0.3 + t * 0.7) * 30 * (Math.random() - 0.5);
const px = cx + (dist + scatter) * Math.cos(spiralAngle);
const py = cy + (dist + scatterY) * Math.sin(spiralAngle) * 0.6; // flatten
// Brightness falls off with distance
const brightness = 0.3 + 0.7 * Math.exp(-t * 2);
const size = 0.5 + Math.random() * 1.5 * (1 - t * 0.5);
// Color: core is warm, outer is blue
const hue = 30 + t * 200;
particles.push({ x: px, y: py, size, brightness, hue, dist });
}
let rotation = 0;
function draw() {
ctx.fillStyle = 'rgba(5, 3, 15, 0.15)';
ctx.fillRect(0, 0, 800, 600);
rotation += 0.003;
for (const p of particles) {
// Rotate around center (inner rotates faster)
const speed = rotation * (200 / (p.dist + 50));
const cos = Math.cos(speed);
const sin = Math.sin(speed);
const dx = p.x - cx;
const dy = p.y - cy;
const rx = cx + dx * cos - dy * sin;
const ry = cy + dx * sin + dy * cos;
ctx.beginPath();
ctx.arc(rx, ry, p.size, 0, Math.PI * 2);
ctx.fillStyle = `hsla(${p.hue}, 60%, ${50 + p.brightness * 30}%, ${p.brightness})`;
ctx.fill();
}
// Bright core
const grad = ctx.createRadialGradient(cx, cy, 0, cx, cy, 40);
grad.addColorStop(0, 'rgba(255, 240, 200, 0.15)');
grad.addColorStop(1, 'rgba(255, 240, 200, 0)');
ctx.fillStyle = grad;
ctx.fillRect(cx - 40, cy - 40, 80, 80);
ctx.fillStyle = '#ffffff';
ctx.font = '14px monospace';
ctx.fillText('Fibonacci Spiral Galaxy — golden ratio arm spacing', 20, 30);
requestAnimationFrame(draw);
}
draw();
Real spiral galaxies don't perfectly follow the golden spiral, but logarithmic spirals (of which the golden spiral is a special case) do describe their arm structure well. The reason is density waves — zones of higher gravitational compression that propagate through the rotating disk. The mathematics of these waves naturally produces logarithmic spirals.
7. Golden angle tree — Fibonacci branching
Trees in nature often branch at angles related to the golden ratio. This ensures leaves don't shadow each other — each new branch grows in a direction maximally different from all previous ones (the same principle as phyllotaxis). We grow a recursive tree where each branch splits at the golden angle:
const canvas = document.createElement('canvas');
canvas.width = 800; canvas.height = 600;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#0a0a0a';
ctx.fillRect(0, 0, 800, 600);
const goldenAngle = Math.PI * (3 - Math.sqrt(5)); // ≈ 2.399 rad ≈ 137.5°
const phi = (1 + Math.sqrt(5)) / 2;
function branch(x, y, angle, length, depth, maxDepth) {
if (depth > maxDepth || length < 3) return;
const endX = x + Math.cos(angle) * length;
const endY = y + Math.sin(angle) * length;
const t = depth / maxDepth;
const hue = 90 + t * 180; // green → blue
const thickness = (1 - t) * 6 + 1;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(endX, endY);
ctx.strokeStyle = `hsl(${hue}, 55%, ${40 + t * 25}%)`;
ctx.lineWidth = thickness;
ctx.lineCap = 'round';
ctx.stroke();
// Branch using golden angle offset
const shrink = 1 / phi; // branches shrink by golden ratio
const newLen = length * shrink;
// Main branch (slight turn)
branch(endX, endY, angle - goldenAngle * 0.3, newLen * 1.05, depth + 1, maxDepth);
// Side branch (golden angle turn)
branch(endX, endY, angle + goldenAngle * 0.5, newLen * 0.85, depth + 1, maxDepth);
// Occasional third branch at deeper levels
if (depth > 2 && depth % 3 === 0) {
branch(endX, endY, angle - goldenAngle * 0.7, newLen * 0.65, depth + 1, maxDepth);
}
// Leaf dots at tips
if (depth === maxDepth - 1 || length < 8) {
ctx.beginPath();
ctx.arc(endX, endY, 2 + Math.random() * 3, 0, Math.PI * 2);
ctx.fillStyle = `hsla(${60 + Math.random() * 40}, 70%, 55%, 0.7)`;
ctx.fill();
}
}
branch(400, 580, -Math.PI / 2, 120, 0, 11);
ctx.fillStyle = '#ffffff';
ctx.font = '14px monospace';
ctx.fillText('Golden Angle Tree — branches at φ-derived angles', 20, 30);
ctx.font = '11px monospace';
ctx.fillStyle = 'rgba(255,255,255,0.6)';
ctx.fillText(`Branch ratio: 1/φ ≈ ${(1/phi).toFixed(4)} — golden angle: 137.5°`, 20, 52);
The tree shrinks each branch by a factor of 1/φ — the reciprocal of the golden ratio. This means two consecutive branches together equal the length of their parent (since 1/φ + 1/φ² = 1). This is essentially the Fibonacci property — each level is the sum of the two below it — expressed as geometry.
8. Generative Fibonacci art — everything combined
Our final piece combines phyllotaxis, golden spirals, and Fibonacci numbers into a single animated composition. Seeds spiral outward using the golden angle. A golden spiral overlay connects the Fibonacci-numbered seeds. The whole piece pulses with slow breathing animation:
const canvas = document.createElement('canvas');
canvas.width = 800; canvas.height = 600;
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
const phi = (1 + Math.sqrt(5)) / 2;
const goldenAngle = Math.PI * (3 - Math.sqrt(5));
const cx = 400, cy = 300;
// Pre-generate Fibonacci set for highlighting
const fibSet = new Set();
let a = 1, b = 1;
while (b < 800) { fibSet.add(b); const t = a + b; a = b; b = t; }
let time = 0;
function draw() {
ctx.fillStyle = 'rgba(8, 5, 20, 0.08)';
ctx.fillRect(0, 0, 800, 600);
time += 0.01;
const numSeeds = 500;
const breathe = 1 + Math.sin(time * 0.5) * 0.05;
// Draw connection lines between adjacent seeds
let prevX, prevY;
for (let i = 1; i < numSeeds; i++) {
const angle = i * goldenAngle + time * 0.1;
const r = Math.sqrt(i) * 10 * breathe;
const x = cx + r * Math.cos(angle);
const y = cy + r * Math.sin(angle);
if (prevX !== undefined && i < 100) {
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(x, y);
ctx.strokeStyle = `rgba(255, 255, 255, ${0.03 * (1 - i/100)})`;
ctx.lineWidth = 0.5;
ctx.stroke();
}
prevX = x;
prevY = y;
}
// Draw seeds
for (let i = 1; i < numSeeds; i++) {
const angle = i * goldenAngle + time * 0.1;
const r = Math.sqrt(i) * 10 * breathe;
const x = cx + r * Math.cos(angle);
const y = cy + r * Math.sin(angle);
const isFib = fibSet.has(i);
const pulse = Math.sin(time * 2 + i * 0.1) * 0.3 + 0.7;
const hue = (angle * 180 / Math.PI + time * 20) % 360;
if (isFib) {
// Fibonacci-numbered seeds glow bright
ctx.beginPath();
ctx.arc(x, y, 8 + Math.sin(time * 3) * 2, 0, Math.PI * 2);
ctx.fillStyle = `hsla(${hue}, 80%, 70%, 0.3)`;
ctx.fill();
ctx.beginPath();
ctx.arc(x, y, 5, 0, Math.PI * 2);
ctx.fillStyle = `hsl(${hue}, 90%, 75%)`;
ctx.fill();
// Label
ctx.fillStyle = '#ffffff';
ctx.font = '9px monospace';
ctx.textAlign = 'center';
ctx.fillText(String(i), x, y - 10);
} else {
const size = 1.5 + pulse;
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI * 2);
ctx.fillStyle = `hsla(${hue}, 55%, 50%, ${0.4 + pulse * 0.3})`;
ctx.fill();
}
}
// Draw golden spiral overlay
ctx.beginPath();
ctx.strokeStyle = 'rgba(255, 215, 100, 0.25)';
ctx.lineWidth = 1.5;
for (let t = 0; t < 800; t++) {
const a2 = t * 0.02 + time * 0.1;
const r2 = 3 * Math.pow(phi, a2 / (Math.PI * 2)) * breathe;
const sx = cx + r2 * Math.cos(a2);
const sy = cy + r2 * Math.sin(a2);
if (t === 0) ctx.moveTo(sx, sy);
else ctx.lineTo(sx, sy);
if (r2 > 350) break;
}
ctx.stroke();
ctx.fillStyle = '#ffffff';
ctx.font = '14px monospace';
ctx.textAlign = 'left';
ctx.fillText('Generative Fibonacci Art — phyllotaxis + golden spiral', 20, 30);
ctx.font = '11px monospace';
ctx.fillStyle = 'rgba(255,255,255,0.5)';
ctx.fillText('Highlighted: Fibonacci-numbered seeds (1, 1, 2, 3, 5, 8, 13, 21...)', 20, 52);
requestAnimationFrame(draw);
}
draw();
The labeled Fibonacci seeds trace out the spiral structure that emerges from the golden angle. This is the deep connection: the Fibonacci sequence, the golden ratio, the golden angle, and the golden spiral are all manifestations of the same underlying mathematical constant φ. Change one, and you change them all.
The mathematics of φ
The golden ratio φ = (1 + √5) / 2 is unique among numbers. It's the positive solution to x² = x + 1, which means φ² = φ + 1, and therefore 1/φ = φ - 1. No other positive number has the property that its square and its reciprocal differ from it by exactly 1.
This self-referential quality is why φ appears in recursive systems. The Fibonacci recurrence F(n) = F(n-1) + F(n-2) has φ as its growth rate because φ is the eigenvalue of the matrix [[1,1],[1,0]]. Phyllotaxis uses the golden angle because φ is the "most irrational" number — its continued fraction [1; 1, 1, 1, ...] converges more slowly than any other, meaning the golden angle maximally avoids alignment.
Key properties:
- Golden ratio: φ = 1.6180339887... = (1 + √5) / 2
- Golden angle: 360° / φ² = 360° × (2 - φ) ≈ 137.5077...°
- Fibonacci growth: F(n) / F(n-1) → φ as n → ∞
- Self-similarity: φ = 1 + 1/φ (the whole relates to its parts as the larger part relates to the smaller)
- Continued fraction: φ = 1 + 1/(1 + 1/(1 + 1/(1 + ...))) — the simplest infinite continued fraction
Fibonacci in nature — a gallery
The golden ratio appears across scales and kingdoms:
- Sunflowers: seed spirals in counts of 34/55 or 55/89 (consecutive Fibonacci numbers)
- Pine cones: 8 spirals one way, 13 the other (8 and 13 are Fibonacci)
- Pineapples: 8 rows of scales one way, 13 the other, 21 the third
- Romanesco broccoli: fractal buds arranged in Fibonacci spirals, with each bud being a miniature copy of the whole — one of the most stunning examples of mathematical self-similarity in nature
- Nautilus shells: chambers grow by a factor close to (but not exactly) φ per quarter turn
- Hurricane structure: cloud bands form logarithmic spirals related to the golden spiral
- Galaxies: arm spacing follows logarithmic spiral curves
- DNA helix: the double helix measures 34 angstroms per full turn and 21 angstroms wide — the ratio 34/21 ≈ 1.619, almost exactly φ
Where to go from here
- Explore mathematical art for more equation-driven visuals — rose curves, superformula shapes, and strange attractors
- Create spirograph patterns that use the golden ratio as their gear ratio for especially intricate curves
- Combine Fibonacci spirals with strange attractors — the Lorenz attractor's fractal dimension involves irrational constants that rhyme with φ's properties
- Add Perlin noise to phyllotaxis parameters for organic, wind-blown sunflower patterns
- Use color theory to map Fibonacci position to harmonious color palettes — the golden ratio itself can generate beautiful color distributions around the hue wheel
- Animate particle systems along golden spiral paths for swirling, natural-looking motion
- On Lumitree, several micro-worlds use Fibonacci-based growth patterns — seeds spiral outward using the golden angle, creating organic structures that mirror the mathematics of living plants