CLICK TO SEE SEXY CURVES (NOT CLICKBAIT)

The maths behind the Spirograph toy.

September 11, 2019

A year ago, I was introduced to the Spirograph toy when I was looking for a gift I could 3-D print for a friend. (Yes, I’m 20 years late.) Whilst I was realising what was missing from my childhood and wasting tons of paper, I could not stop thinking about the maths behind it. So here is a fun post about the maths behind the Spirograph toy, complete with some sexy curves (SFW) created using my Spirograph web app.

Roulettes

Let’s start with the equation of the curves formed by the Spirograph toy. In order to understand how the Spirograph works, we need to first learn some geometry of curves.

A roulette is the curve traced by a fixed point on a closed convex curve that rolls along another secondary curve without slipping.

Animation of roulette

Animation of roulette

[Source: Wolfram MathWorld]

The Spirograph toy traces out two kinds of roulettes, namely hypotrochoids and epitrochoids.

Hypotrochoids

A hypotrochoid is a roulette in which the fixed point is attached to a circle that rolls inside a stationary circle. We can draw hypotrochoids with the Spirograph by rolling the wheel around the inside of the ring.

Hypotrochoid Hypotrochoid
Values for LHS curve: R=320R = 320, r=105r = 105, p=70p = 70. Values for RHS curve: R=320R = 320, r=210r = 210, p=160p = 160. Screenshots taken with the save image feature from my web app.

Let RR be the radius of the stationary circle, rr be the radius of the rotating circle, pp be the distance of the fixed point from the center of the rotating circle and a parameter tt be the angle formed by the horizontal and the centre of the rotating circle.

Animation of hypotrochoid [Source: Sam Derbyshire]

The centre of the rotating circle is always RrR - r distance away from the centre of the fixed circle. This circle also obeys circular motion. If we assume our fixed circle is centred at the origin on the Cartesian plane, like in the animation above, we get the following parametric equations for the centre of the rotating circle:

xc(t)=(Rr)cos(t)x_c(t) = (R - r)\cos(t) yc(t)=(Rr)sin(t)y_c(t) = (R - r)\sin(t)

We also need to derive the position of the fixed point relative to the centre of the rotating circle.

(Note that in the animation above, the fixed point is outside the rotating circle. Whilst this fixed point is still ‘attached’ to the rotating circle, making it a hypotrochoid, this technically is not possible with the physical Spirograph toy.)

Because the parameter tt is the angle formed by the horizontal and the centre of the rotating circle, our relative parameter tt', which represents the angle formed by the radius of the rotating circle parallel to the horizontal and the fixed point, can be expressed as:

t=Rrrtt' = -\frac{R - r}{r} t

Why is it negative? Well, if we have the rotating circle move inside the fixed circle in a counterclockwise direction, like in the animation above, we can see that the circle actually rotates in a clockwise direction. This means that our fixed point will always move around the centre of the rotating circle in the opposite direction that the rotating circle moves around the centre of the fixed circle.

Our fixed point also obeys circular motion, therefore the parametric equations for the fixed point relative to the centre of the rotating circle are:

xpc(t)=pcos(Rrrt)x_{p_c}(t) = p\cos(-\frac{R - r}{r} t) ypc(t)=psin(Rrrt)y_{p_c}(t) = p\sin(-\frac{R - r}{r} t)

We can now add the xcx_c to xpcx_{p_c} and ycy_c to ypcy_{p_c} find the parametric equations for a hypotrochoid:

x(t)=(Rr)cos(t)+pcos(Rrrt)x(t) = (R - r)\cos(t) + p\cos(\frac{R - r}{r} t) y(t)=(Rr)sin(t)psin(Rrrt)y(t) = (R - r)\sin(t) - p\sin(\frac{R - r}{r} t)

Epitrochoids

An epitrochoid is a roulette in which the fixed point is attached to a circle that rolls along the outside of a stationary circle. We can draw epitrochoids with the toy by rolling the wheel around the outside of the ring.

Epitrochoid Epitrochoid
Values for LHS curve: R=250R = 250, r=85r = 85, p=70p = 70. Values for RHS curve: R=100R = 100, r=95r = 95, p=140p = 140.

Again let RR be the radius of the stationary circle, rr be the radius of the rotating circle, pp be the distance of the fixed point from the center of the rotating circle and a parameter tt be the angle formed by the horizontal and the centre of the rotating circle.

Animation of Epitrochoid [Source: Sam Derbyshire]

Our parametric equations for an epitrochoid are similar to the hypotrochoid. Instead, the centre of the rotating circle is always R+rR + r distance away from the centre of the fixed circle, and because our fixed point will be moving around the centre of the rotating circle in the same direction the rotating circle moves around the centre of the fixed circle, our relative parameter tt' is now:

t=R+rrtt' = \frac{R + r}{r} t

Thus, the parametric equations for an epitrochoid are:

x(t)=(R+r)cos(t)pcos(R+rrt)x(t) = (R + r)\cos(t) - p\cos(\frac{R + r}{r} t) y(t)=(R+r)sin(t)psin(R+rrt)y(t) = (R + r)\sin(t) - p\sin(\frac{R + r}{r} t)

Implementing the Spirograph

As we saw earlier, these parametric equations can be split into two terms. The first term (e.g. (Rr)cos(t)(R - r)\cos(t) for the x-coordinate of a hypotrochoid) expresses the position of the rotating circle relative to the centre of the fixed circle. Thus, in the updateSpiro() function of the web app, we get:

posr = {x: mainCanvas.width / 2 + (R-r) * Math.cos(t), y: mainCanvas.height / 2 + (R-r) * Math.sin(t)};

for a hypotrochoid, and

posr = {x: mainCanvas.width / 2 + (R+r) * Math.cos(t), y: mainCanvas.height / 2 + (R+r) * Math.sin(t)};

for an epitrochoid. This allows us to draw the rotating circle rolling around the stationary circle.

The second term (e.g. psin(Rrrt)-p\sin(\frac{R - r}{r} t) for the y-coordinate of an epitrochoid) expresses the position of the pen relative to the centre of the rotating circle. Therefore, adding the terms gives us the position of the pen relative to the centre of the fixed circle. In the updateSpiro() function below the previous lines, we get:

posPen = {x: posr.x + p * Math.cos((R-r) / r * t), y: posr.y - p * Math.sin((R-r) / r * t)};

for a hypotrochoid, and

posPen = {x: posr.x - p * Math.cos((R+r) / r * t), y: posr.y - p * Math.sin((R+r) / r * t)};

for an epitrochoid. Now that we have the absolute position of the fixed point, or pen, we can display the actual result of the spirograph.

Deriving the number of petals

Let’s recall that our parameter tt is the angle formed by the horizontal and the centre of the rotating circle. When measured in radians, tt takes the values 0 to 2πLCM(R,r)r2\pi\frac{LCM(R, r)}{r} where LCMLCM is a function that returns the lowest common multiple. This means that the rotating circle will complete LCM(R,r)r\frac{LCM(R, r)}{r} revolutions, thus the Spirograph curve will have LCM(R,r)r\frac{LCM(R, r)}{r} petals. Pretty neat, right?

(In my Spirograph web app, I use this fact to ensure that the parametric equations for generating the multi-colour gradient pen ends at 2π2\pi, in order to make the Spirograph curve look seamless. The whole colour theory behind this deserves its own post, but for now here is a link to a great post about this.)

Fortunately, calculating the LCM(x,y)LCM(x, y) for two numbers xx and yy is as simple as:

LCM(x,y)=xyGCD(x,y)LCM(x, y) = \frac{|x \cdot y|}{GCD(x, y)}

where GCDGCD is a function that returns the greatest common divisor. In order to obtain the GCDGCD, we can use the Euclidean algorithm:

// Calculate the greatest common divisor of two numbers
function gcd(x, y) {
	while(y) {
		var tmp = y;
		y = x % y;
		x = tmp;
  	}
  	return x;
}

Now we can calculate the number of petals a Spirograph curve will have. Inserted below are a hypotrochoid and epitrochoid drawn using the same values: R=250R = 250, r=80r = 80 and p=50p = 50:

Hypotrochoid Epitrochoid

If you count the number of petals for both the hypotrochoid and epitrochoid, both the hypotrochoid and epitrochoid have 25 petals. Let’s check that:

LCM(250,80)80=25080GCD(250,80)80=25010=25\frac{LCM(250, 80)}{80} = \frac{|250 \cdot 80|}{GCD(250, 80) \cdot 80} = \frac{250}{10} = 25

Hypocycloids and epicycloids

Hypocycloids and epicycloids are very similar to hypotrochoids and epitrochoids, however the fixed point is always on the circumference of the rotating circle. This means that we can reduce the equation for a hypotrochoid and epitrochoid to that for a hypocycloid and epicycloid.

This time, let’s say the radius of the larger circle RR is equal to krkr, remembering rr is the radius of the smaller circle. We can now write the parametric equations as:

x(t)=r(k1)cos(t)+rcos((k1)t)x(t) = r(k - 1)\cos(t) + r\cos((k - 1)t) y(t)=r(k1)sin(t)rsin((k1)t)y(t) = r(k - 1)\sin(t) - r\sin((k - 1)t)

for a hypocycloid, and

x(t)=r(k+1)cos(t)rcos((k+1)t)x(t) = r(k + 1)\cos(t) - r\cos((k + 1)t) y(t)=r(k+1)sin(t)rsin((k+1)t)y(t) = r(k + 1)\sin(t) - r\sin((k + 1)t)

for an epicycloid. Why write it in this way instead? The number of cusps, or sharp corners on the curve, is directly correlated to the ratio of the radius of larger circle to the radius of the smaller circle, or Rr\frac{R}{r}. Thus, the number of cusps is directly correlated to kk.

If kk is an integer, the curve has kk cusps:

k = 3 k = 4 k = 5 k = 6 k = 7
Hypocycloid Hypocycloid Hypocycloid Hypocycloid Hypocycloid
Hypocycloids with integer kk values.
k = 1 k = 2 k = 3 k = 4 k = 5
Epicycloid Epicycloid Epicycloid Epicycloid Epicycloid
Epicycloids with integer kk values.

If kk is a rational number, that is it can be expressed as pq\frac{p}{q} where pp and qq are integers, the curve has pp cusps:

k = 53\frac{5}{3} k = 73\frac{7}{3} k = 83\frac{8}{3} k = 95\frac{9}{5} k = 107\frac{10}{7}
Hypocycloid Hypocycloid Hypocycloid Hypocycloid Hypocycloid
Hypocycloids with rational kk values.
k = 53\frac{5}{3} k = 73\frac{7}{3} k = 83\frac{8}{3} k = 95\frac{9}{5} k = 107\frac{10}{7}
Epicycloid Epicycloid Epicycloid Epicycloid Epicycloid
Epicycloids with rational kk values.

If kk is an irrational number, the curve never closes.


Written by Faisha Surjatin. CS Advanced (Hons) undergrad and AR/VR developer at Monash University. All-round computer science nerd. Not a web dev.