Modeling Math with Python Programming: The Spirograph Program

Hopefully this software does not remind you of the intense amount of snow some of you are getting. I am often inspired by others to create software and when I was browsing the Math.com site one day, I found a beautiful Spirograph applet that I knew I had to try to recreate in Python. I try to impart this to my students, seeing something that you don't initially understand and learning as you go.

It required me to relearn Parametric Equations, refine my knowledge of Class Objects, learn the controlls functions in VPython and push the boundaries of my computer's memory.

In order to run this code you will need:
Python 2.6 - The interpreter for the code. Check out the programming page if you would like to know more about implementing Python or programming in your classroom.
VPython - The visual add on for Python.
Psyco - Speeds up the code significantly so I could run it on older laptops. If you don't want it or need it, feel free to delete the first couple of lines (before the "from visual")

Enjoy the pictures and the code below, and please share any great code you have or suggestions.





Spirograph Maker inspired by http://www.math.com/students/wonders/spirographs.html

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import psyco
psyco.full()
from visual import arange,curve,color,cos,sin,display,rate
from visual.controls import controls, slider,label

iterations = input('How many iterations?')

class spiro():
    def __init__(self,iterations):
        self.R = 65.0 #Radius of Fixed Circle
        self.r = 43.0 #Radius of Moving Circle
        self.o = 75.0 #offset of pen point in moving circle
        self.t = arange(0,iterations,1)
        self.drawing = curve(x = ((self.R+self.r)*cos(self.t) - (self.r+self.o)*cos(((self.R+self.r)/self.r)*self.t)), y = ((self.R+self.r)*sin(self.t) - (self.r+self.o)*sin(((self.R+self.r)/self.r)*self.t)), color = color.green)
    def fixedRadius(self,fRadius):
        self.R = fRadius.value
        self.redraw()
    def rollingRadius(self,rRadius):
        self.r = rRadius.value
        self.redraw()
    def penOffset(self,pOffset):
        self.o = pOffset.value
        self.redraw()
    def redraw(self):
        self.drawing.x = ((self.R+self.r)*cos(self.t) - (self.r+self.o)*cos(((self.R+self.r)/self.r)*self.t))
        self.drawing.y = ((self.R+self.r)*sin(self.t) - (self.r+self.o)*sin(((self.R+self.r)/self.r)*self.t))

class GUI():
    def __init__(self):
        self.c = controls(x=0,y=0,width=400, height = 400, range=100)
        self.s1 = slider(pos=(0,40),width=7, length=40, axis=(1,0,0),min=1,max=100,action=lambda:
                         Spirograph.fixedRadius(self.s1))
        self.s2 = slider(pos=(0,0),width=7, length=40, axis=(1,0,0),min=1,max=100,action=lambda:
                         Spirograph.rollingRadius(self.s2))
        self.s3 = slider(pos=(0,-40),width=7, length=40, axis=(1,0,0),min=1,max=100,action=lambda:
                         Spirograph.penOffset(self.s3))
        self.fixedRadiusLabel = label(pos=self.s1.pos, display = self.c.display, text='Fixed Radius', line = 0,
                                 xoffset=0, yoffset=20, height=10, border=0)
        self.rollingRadiusLabel = label(pos=self.s2.pos, display = self.c.display, text='Rolling Radius', line = 0,
                                   xoffset=0, yoffset=20, height=10, border=0)
        self.penOffsetLabel = label(pos=self.s3.pos, display = self.c.display, text='Pre-Offset', line = 0,
                               xoffset=0, yoffset=20, height=10, border=0)
        self.scene1 = display(title = 'Spirograph!', x=410, y=0, width=400, height = 400)
        self.scene1.select()

WYSIWYG = GUI()
Spirograph = spiro(iterations)

while(1):
    WYSIWYG.c.interact()


Subscribe to BrokenAirplane!