Spiral Growth
About This Sketch
A mathematical spiral that grows outward from the center while continuously rotating. The Archimedean spiral is one of the most elegant mathematical curves, appearing in nature from nautilus shells to galaxy arms.
The gradual color transition along the spiral's path adds visual depth, while the rotation creates a meditative, almost hypnotic motion. This demonstrates how simple mathematical relationships can produce complex, beautiful forms.
Algorithm
An Archimedean spiral that rotates continuously, creating a hypnotic spinning effect. The spiral's radius increases linearly with angle, following the equation r = a × θ.
**Key Concepts:**
- **Archimedean Spiral**: r = a × θ (radius proportional to angle)
- **Polar Coordinates**: Converting (r, θ) to (x, y) Cartesian coordinates
- **Rotation Transform**: Incrementing base angle to rotate the entire spiral
- **Color Transition**: Multi-stage gradient along the spiral path
**How it works:**
1. For each point along the spiral (0 to 360 degrees)
2. Calculate radius as linear function of angle: r = i × 0.3
3. Add rotation offset to create spinning motion
4. Convert polar to Cartesian: x = r × cos(θ), y = r × sin(θ)
5. Interpolate colors progressively along the spiral
6. Increment rotation angle each frame
Pseudocode
SETUP:
angle = 0
radius = 0
DRAW (every frame):
CLEAR background
MOVE origin to center
FOR i = 0 to 360:
r = i × 0.3
theta = radians(i) + angle
x = r × cos(theta)
y = r × sin(theta)
color_position = i / 360
color = interpolate_gradient(color_position)
DRAW point at (x, y)
angle = angle + 0.02
Source Code
let sketch = function(p) {
let angle = 0;
let radius = 0;
p.setup = function() {
p.createCanvas(400, 300);
p.colorMode(p.RGB);
};
p.draw = function() {
const colors = getThemeColors();
p.background(...colors.bg);
p.translate(p.width/2, p.height/2);
p.beginShape();
p.noFill();
for (let i = 0; i < 360; i++) {
let r = i * 0.3;
let a = p.radians(i) + angle;
let x = r * p.cos(a);
let y = r * p.sin(a);
let t = p.map(i, 0, 360, 0, 1);
let col = t < 0.5 ?
colors.accent1.map((c, idx) => p.lerp(c, colors.accent2[idx], t * 2)) :
colors.accent2.map((c, idx) => p.lerp(c, colors.accent3[idx], (t - 0.5) * 2));
p.stroke(...col);
p.strokeWeight(3);
p.point(x, y);
}
p.endShape();
angle += 0.005;
};
};