from Tkinter import * #need Tkinter module for graphics from math import * #need math module for floor, pi, cos, sin, etc. v=10. #initial speed, i.e., magnitude of displacement, in meters/second g=9.80 #gravitational acceleration in meters/second/second #for canvas coordinate system canvas_width=400 canvas_height=400 #for our x-y coordinate system xmin=-1 xmax=11 ymin=0 ymax=12 #The canvas coordinate system is different from usual x-y coordinate system #In the canvas system, the upper left corner is (0,0) and y points down. #In our x-y system, y points up. #In both systems, x points to the right. #these two functions convert from our x-y system to the canvas system def canvas_x(x, a=xmin, b=xmax, width=canvas_width): #floor rounds down to nearest whole number return (x - a) * width / (b - a) def canvas_y(y, a=ymin, b=ymax, height=canvas_height): return (b - y) * height / (b - a) degree=pi/180. #1 degree equals pi/180 radians class Simulation(): """ draws parabola and outputs final horiztonal position rx0 is initial x position ry0 is initial y position theta0 is initial direction of velocity v0 is initial magnitude of velocity ax is constant horizontal acceleration ay is constant horizontal acceleration dt is time increment size in seconds g is graviational acceleration in meters/second/second """ def __init__(self, rx0, ry0, theta0, v0, ay, dt): self.ax = 0 self.ay = ay self.v0 = v0 self.theta0 = theta0 self.vx = v0 * cos(theta0) self.vy = v0 * sin(theta0) self.rx = rx0 self.ry = ry0 self.dt = dt self.t = 0 self.disp_theory = -2 * self.vx * self.vy / ay self.time_theory = -2 * self.vy / ay cx = canvas_x(rx0) cy = canvas_y(ry0) self.make_circle(cx, cy) self.advance() def make_circle(self, cx, cy, rad=2): self.circle = canvas.create_oval(cx-rad,cy-rad,cx+rad,cy+rad, width=0,fill='red') def advance(self): if self.ry > 0 or self.vy > 0: #if before impact: #'c' for 'canvas' #'s' for 'start' of line segment cxs = canvas_x(self.rx) cys = canvas_y(self.ry) dvx = self.ax * self.dt dvy = self.ay * self.dt self.vx = self.vx + dvx self.vy = self.vy + dvy drx = self.vx * self.dt dry = self.vy * self.dt self.rx = self.rx + drx self.ry = self.ry + dry self.t = self.t + self.dt #'f' for 'finish' of line segment cxf = canvas_x(self.rx) cyf = canvas_y(self.ry) #make short line segment from old position (rx,ry) to #esimated new position (rx,ry) at time dt later. canvas.create_line(cxs, cys, cxf, cyf) canvas.delete(self.circle) #delete old circle self.make_circle(cxf, cyf) #replace with new circle #wait self.dt * 1000 milliseconds, then advance again canvas.after(int(self.dt * 1000), self.advance) else: #if after impact: disp_sim = self.rx print (self.v0, round(self.theta0 / degree, 3), round(disp_sim, 3), round(self.disp_theory, 3), round(self.t, 3), round(self.time_theory, 3)) #create window master = Tk() #create 'canvas' that we draw lines on canvas = Canvas(master, width=canvas_width, height=canvas_height, bg='white') #actually displays canvas in window canvas.pack() print "Speed is initial velocity is in meters/second." print "Angle is in degrees and measures initidal velocity angle with x-axis." print "Displacement is in meters and measured at impact." print "Time is time elapsed in seconds." print "(speed", print "angle, ", print "simulated displacement, ", print "theoretical displacement, ", print "simulated time, ", print "theoretical time):" angles = range(0,95,5) disp_theory = dict() sim = dict() for angle in angles: theta=angle * degree Simulation(rx0 = 0, ry0 = 0, v0 = v, theta0 = theta, ay = -g, dt = 0.01) #actually display window mainloop()