As a kid, one of my favorite toys was my Spirograph Set. I had the original 1960s version, as pictured in that link. I still remember being completely blown away by how some plastic gears and colored ballpoint pens could produce a near-infinite variety of intricate geometric patterns. Yeah, I was already a bit of a geek even when I was 7 years old!
Somewhere along my meandering journey from childhood to middle age, my Spirograph set was lost. But a recent query from my wife (who has become interested in geometric designs for art quilts) rekindled my interest in this long-lost toy. I haven’t gone and bought an old Spirograph set on eBay (yet…), but I’ve done the next best (in some ways better!) thing.
With a bit of research on Wikipedia and Wolfram MathWorld, I’ve learned that Spirograph produces mathematical curves called hypotrochoids and epitrochoids. In a nutshell, if you take a fixed circle, roll another circle around its inner or outer circumference, and affix a pen at some distance from the rolling circle’s center, the pen traces a hypotrochoid (if the rolling circle is inside the fixed one) or an epitrochoid (if the rolling circle is outside the fixed one). The number of lobes in the pattern depends on the ratio of the sizes of the fixed and rolling circles, and the shape of the lobes (how pointy or rounded they are) is determined by both the ratio of the sizes of the circles and the distance of the pen from the moving circle’s center.
It’s a fairly simple matter to simulate arbitrary Spirograph patterns on a PC, and display the results in a window. I’ve written a simple Python script to do this—I call it Pyrograph, and you can grab the (admittedly rather primitive) v0.1 release of it here (right-click the link, and save the file locally). Update: There’s a v0.2 release here, which fixes the issue when executing from within the Python Idle environment that someone reported in the comments. It has also been noted that the Windows-style line endings in the file can cause problems for Linux users ("bad interpreter" errors); Linux users should convert the line endings using the dos2unix command before attempting to run the script.
To play with the script yourself, you’ll need to install the Python interpreter on your system. Python is a freely available, Open Source, cross-platform scripting language that has a huge number of add-on packages available for various application areas. For Windows, simply download and run the installer for the latest 2.x release, which should be available from this page. If you’re a Tux fan, install the base Python package and the "tkinter" add-on from your Linux distro’s software repository (many distros install the Python interpreter by default, so you may need to install only tkinter).
Take a look at the Pyrograph script in your favorite plain-text editor (even Notepad will do in a pinch). The Pyro method is the heart of the script; the first parameter is the radius of the fixed circle, the second parameter is the radius of the rolling circle, the third parameter is the offset of the pen from the center of the rolling circle, the fourth parameter rotates the entire pattern a specified number of degrees, the fifth parameter scales the entire pattern up or down in size (values > 1 enlarge it, values < 1 shrink it), and the sixth parameter specifies the color of the pen.
The Draw method is invoked when the script is run; it calls the Pyro method one or more times. To change the pattern, edit the Draw method. To see the pattern, just run the script (type its name in a command prompt window, or double-click on the file).
For each of the following examples, I’ve listed the Draw method, immediately followed by a screen capture of the pattern it produces. (Other than the Draw method, the rest of the script remains unchanged.)
# Example #1: Simple hypotrochoid pattern, with the rolling circle fairly large and the pen near its edge
def Draw(self):
self.Pyro(300, 255, 220, 0, 1, "#0000c0")
# Example #2: Same as previous, but with the pen moved in towards the center of the rolling circle
def Draw(self):
self.Pyro(300, 255, 80, 0, 1, "#0000c0")
# Example #3: Hypotrochoid with a smaller radius rolling circle
def Draw(self):
self.Pyro(300, 45, 35, 0, 1, "#0000c0")
# Example #4: Multiple overlaid hypotrochoids (different pen offset for each)
def Draw(self):
for i in range(0, 15):
self.Pyro(300, 200, 50 + i * 10, 0, 1, "#0000c0")
# Example #5: Same as previous, but with each iteration rotated by a multiple of 5 degrees
def Draw(self):
for i in range(0, 15):
self.Pyro(300, 200, 50 + i * 10, i * 5, 1, "#0000c0")
# Example #6: A simple epitrochoid
def Draw(self):
self.Pyro(150, -60, 50, 0, 1, "#0000c0")
# Example #7: Some multi-colored epitrochoids
def Draw(self):
for i in range(0, 24, 4):
self.Pyro(150, -60, 50, i, 1, "#c00000")
self.Pyro(150, -60, 50, i + 24, 1, "#00c000")
self.Pyro(150, -60, 50, i + 48, 1, "#0000c0")
Well, I hope that’s piqued your interest. Have fun!