""" Program "Lissajous Explorer" by Erik Nelson, (c)June 2007 This is a program written with Python and Tkinter, which explores Lissajous figures. The pitch and phase of the sine wave that drives the vertical coordinate are adjustable with controls on the left and the controls for the horizontal coordinate are on the bottom. The phase slider is scaled so 0 to 100 is a half wavelength. The two sine waves are functions of the variable t, which stands for time. buttons: "erase" just clears the screen. "t=0" resets t to zero and clears the screen. (this is needed because if you left it running for a long time, t would get huge and we would get weird floating point rounding errors. I have not seen this happen yet though.) "bye" quits the program. """ from Tkinter import * from math import * t=0 xcenter=250 ycenter=250 xheight=200 yheight=200 xpitch=.01 #This value is not used, but I still need to declare the var ypitch=.01 #This value is not used, but I still need to declare the var xoffset=.5 #This value is not used, but I still need to declare the var yoffset=.5 #This value is not used, but I still need to declare the var def xcoord(T): return xheight * sin( xpitch * T + (xoffset * pi ) ) + xcenter def ycoord(T): return yheight * sin( ypitch * T + (yoffset * pi ) ) + ycenter class Ani(Frame): def printit(self): print "hi, my t is equal to",t def tick(self): global t t=t+1 def createWidgets(self): self.QUIT = Button(self, text = 'bye', foreground='red', command=self.quit) self.QUIT.grid(column=3, row=5) self.ZERO = Button(self, text = 't=0', command = self.zerot) self.ZERO.grid(column=3,row=2) self.ERASE = Button(self, text = 'erase', foreground='red', command = self.clear) self.ERASE.grid(column=3,row=1) ## The ypitch control self.yptch = Scale(self, orient=VERTICAL, label="y_pitch", from_=1, to=100) self.yptch.grid(column=1,row=2) self.yptch.set(50) ## The xpitch control self.xptch = Scale(self, orient=HORIZONTAL, label="x_pitch", from_=1, to=100) self.xptch.grid(column=2, row =5,) self.xptch.set(30) ## The x offset control self.xofst = Scale(self, orient=HORIZONTAL, label="x phase offset", from_= -100, to =100) self.xofst.grid(column=2, row=6) ## The y offset control self.yofst = Scale(self, orient=VERTICAL, label="y phase offset", from_= -100, to =100) self.yofst.grid(column=1, row=3) self.draw = Canvas(self, width=500,height=500) self.draw.grid(column=2, row=1, rowspan=3) def dotter(self): global xpitch global ypitch global xoffset global yoffset xpitch = .001 * self.xptch.get() ypitch = .001 * self.yptch.get() xoffset = .01 * self.xofst.get() yoffset = .01 * self.yofst.get() self.draw.create_rectangle(xcoord(t), ycoord(t), xcoord(t) +1, ycoord(t)+1, fill="black") self.tick() #self.printit() self.after(1, self.dotter) def clear(self): """self.draw.create_rectangle( 1,1,499,499, fill="white", outline = "white")""" self.draw.delete(ALL) def zerot(self): global t t = 0 self.clear() def __init__(self, master=None): Frame.__init__(self, master) Pack.config(self) self.createWidgets() self.after(10, self.dotter) ani = Ani() ani.mainloop()