Drawing by Epicycles

Introduction to Epicycles

Imagine you followed a single point on the edge of a rotating disk. If you traced it out for a full cycle, you'd get a circle:

If you wanted to express this path as a math equation, we could say the x and y coordinates of the point on the path drawn at time \(t\) is given by:

\[ \begin{aligned} x(t) & = R\cos(\omega t)\\ y(t) & = R\sin(\omega t)\\ \end{aligned} \]

Where \(R\) is the radius of the disk and \(\omega\) is the speed at which the disk is rotating. This type of formula is called a Parametric Equation — if it looks unfamiliar to you, it's worth reading up on Parametric Equations a bit before continuing.

Now let's get just a little more complex: let's say you added a second rotating disk and traced a point around its edge, you'd get a flower shape:

Turning this more complex path into an equation isn't too hard either: the overall position is just the sum of the contributions from each disk. More formally, the point at time t is the the position at time t due to the first disk plus the position at time t due to the second disk:

\[ \begin{aligned} x(t) & = R_1\cos(\omega_1 t) + R_2\cos(\omega_2 t)\\ y(t) & = R_1\sin(\omega_1 t) + R_2\sin(\omega_2 t)\\ \end{aligned} \]

Here \(R_1\) is the radius of the first, inner disk and \(R_2\) is the radius of the second, outer disk. We'll be using subscript notation throughout to keep track of both the radii of the disks (\(R_i\)) and the speed that they're rotating at (\(\omega_i\)).

By adding additional disks and varying their speeds and sizes, you can get increasing complex curves, called epicycles

Epicycles are curves governed by the equations:

\[ \begin{aligned} x(t) & = \sum_i R_i\cos(\omega_i t + \phi_i)\\ y(t) & = \sum_i R_i\sin(\omega_i t + \phi_i)\\ \end{aligned} \]

This new symbol \(\phi_i\) is how much disk \(i\) is initially rotated at time \(t = 0\), called a phase offset. If we don't specify a phase offset, we can only describe epicycles where the circles start neatly aligned, which is only a portion of the full set of epicycles.

Let's dive deeper into what forms these epicycles can take. Do all epicycles have to be "curvy"? Well, if we have two disks rotating in opposite directions, we can create a straight line:

In this case, because the sizes of the circles are the same, the "y" components cancel each other out, and we get:

\[ \begin{aligned} x(t) & = R\cos(\omega t) + R\cos(-\omega t) = R\cos(\omega t) + R\cos(\omega t) = 2R\cos(\omega t)\\ y(t) & = R\sin(\omega t) + R\sin(-\omega t) = R\sin(\omega t) - R\sin(\omega t) = 0\\ \end{aligned} \]

\(y(t)\) is always zero, meaning we draw a straight line along the x axis! Neat! So it looks like we can create epicycles that are simple curves like a circle, crazy complex curves that look like who-knows-what, and a simple straight line. Also, it seems like the more disks we have, the more complex the curves can get. Given this, maybe if we have enough disks, and we choose the right sizes for each of the disks, and have them spin at the appropriate speeds, we can create any closed shape, like:

As you may have guessed by this point, the answer is yes! Using epicycles, we can draw any closed shape, even Homer Simpson.

There's still one unanswered question though - just how exactly do we determine what disks to use, and how fast to spin them? For the epicycle drawing of the letter B above, how did we figure out the values for the various \(R_i, \omega_i,\) and \(\phi_i\) to make the drawing come out right? Let's try to figure it out.

Computing Epicycles for a Path

The first step is formalizing the problem. Rather than saying "the letter B", let's come up with a mathmatical way of describing what we want. Instead of describing a shape that I want, let's say that instead I just specify some points, and then find a formula for "connecting the dots" into the shape that I want. Getting technical, this means that our input is a set of some number of points \((x_j, y_j)\), and we want to find epicycles that best connect those points - the \(R_i, \omega_i,\) and \(\phi_i\) that makes it so

\[ \begin{aligned} x(t) & = \sum_i^N R_i\cos(\omega_i t + \phi_i)\\ y(t) & = \sum_i^N R_i\sin(\omega_i t + \phi_i)\\ \end{aligned} \]

comes as close to the points as possible. Then we can chose the points to draw out the letter B, solve for the variables, and have our epicycle!

Looking at the equations, you'll see we introduced a new variable \(N\): as we noticed before, the more disks we have, the closer we can get, so we'll be specific and state the problem as "If we only have \(N\) disks, what's the best we can do?"

Quick side note: in math there are many ways to say "as close to the points as possible." We'll stick with one of the more common measures called mean square error (as it turns out, this is a great choice and makes our life much easier).

Ok so now we've specified the problem - now what? Well, to be honest, this is about the time when mathematicians bang their head against a wall for a while and hope to come up with something creative. It took this author a couple of years of on-and-off exploration to chance upon something that works. As it turns out, you can use something called Euler's formula and a technique called the Discrete Fourier Transform to solve this problem in a way that is not only elegant, but also very easy for computers to perform. Warning, things are going to get technical very quickly from here on out. Feel free to jump ahead to the playground.

Here's how it works: you'll notice that in the above equations there seem to be a lot of similarities between how we calculate \(x(t)\) and how we calculate \(y(t)\). In fact, the only difference is that one uses "\(\cos\)" and the other uses "\(\sin\)". So maybe there's some way we could "add" the two equations together to simplify our life and only have to deal with one equation instead of two. We can't just add them directly, because we need to keep \(x(t)\) and \(y(t)\) separate, and besides \(\cos\) and \(\sin\) don't add together well anyway. Leap of faith: what if, instead of thinking about our points along the x and y axes, we think about those points as complex numbers along the real and imaginary axes? Seems crazy, but it let's us make headway:

\[ p_j = x_j + iy_j \\ x(t) + iy(t) = \sum_i^N R_i(\cos(\omega_i t + \phi_i) + i\sin(\omega_i t + \phi_i)) \]

Great! We have one formula, and we haven't lost anything: we can still get x by taking the real part, and y by taking the imaginary part of the function. Now we can make use of Euler's formula, and we see that we're looking for the variables such that:

\[ \sum_j^N R_je^{i\omega_j t+ \phi_j} \]

comes as close to the complex points \(p_j\) as possible. Even better, if we allow \(X_j\) to be a complex number, then the formula above becomes:

\[ \sum_j^N X_je^{i\omega_j t} \]

We'll make one final assumption to simplify things: rather than choosing \(N\) arbitrary speeds \(\omega\), we'll make the speeds be 0 (stationary), 1x, -1x, 2x, -2x, 3x, -3x, ... N/2x, -N/2x. With this simplification, we can make the final leap express our problem as:

Find the complex numbers \(X_i\) to minimize the mean squared error between the complex points \(p_j\) and the curve

\[ p(t) = \sum_{j=0}^N X_je^{\frac{2\pi i j}{N}t} \]

It took a lot of work to get here, but it was worth it. As it turns out, the form above almost identically matches the form of what's called the Discrete Fourier Transform. This means we can use the discrete fourier transform on the points we have (the ones that drew out the letter B, remember?), and get the \(X_j\). From that we can get the \(R_j\) and \(\phi_j\), and we know \(\omega_j = \frac{2 \pi i j}{N}\). Voila!

Ok, so how did we know to look at Fourier Transforms? Well, fourier transforms turn formulas with lots of \(\sin\)'s and \(\cos\)'s into sets of complex points and visa versa, so trying it was as good of guess as any, and happened to work out. How did we know to add \(x(t)\) and \(y(t)\) by translating them into the complex plane? Divine inspiration. Just got lucky, really - that's often how math works sometimes when you're figuring out something new.

So there you have it - if we specify a number of points, we can use an epicycle to draw out a curve that connects the dots, and we can use the Discrete Fourier Transform to figure out what that epicycle is. To see this in action, play with the playground below.

Create your own Epicycle Drawings

Try playing around with creating your own drawings using epicycles. You can drag points around, add points by double-clicking, or remove a point by right-clicking on it.