""" ball_arc.py An animation of a ball trajectory, using Zelle's graphics package and some basic physics. Jim Mahoney, Fall 2010, GPL """ # A numeric approximation to the Newton's # equations of motion for a falling ball are # # x(t + dt) = x(t) + Vx * dt # y(t + dt) = y(t) + Vy(t) * dt # Vx = constant # Vy(t + dt) = Vy(t) + g * dt # g = -9.8 m/sec**2 = downward (negative) acceleration from gravity # # which we can implement in python within a loop, # updating the variables and re-positioning the ball # each time throught the loop. from graphics import GraphWin, Point, Line, Circle, Text from time import sleep # -- define a bunch of constants and variables window_right = 20 window_top = 8 window_margin = 2 window_coords = (-window_margin, -window_margin, window_right + window_margin, window_top + window_margin) window_pixel_height = 400 window_pixel_width = window_pixel_height * \ (window_right + 2*window_margin) / \ (window_top + 2*window_margin) window_title = "ball arc" window_background_color = "#e0e0e0" # light grey ball_radius = 0.5 # in meters ball_color = 'red' dt = 0.02 # simluation tick time, in seconds time = 0.0 # elapsed time wait_time = 0.003 # wall clock wait time while ball moves by dt stop_time = 2.0 # simulation stop time, in seconds x = 0 # initial x ball position, in meters y = 0 # ditto for y Vx = 10 # initial x velocity, in meters/sec Vy = 9 # ditto for y g = -9.8 # meters/sec**2, downwards # -- create the window -- window = GraphWin(window_title, window_pixel_width, window_pixel_height) window.setBackground(window_background_color) window.setCoords(window_coords[0], window_coords[1], window_coords[2], window_coords[3]) # -- create and draw a lines for some plot edges ground = Line(Point(0,0), Point(window_right, 0)) ground.setWidth(3) ground.setOutline('#303000') ground.draw(window) wall = Line(Point(0,0), Point(0, window_top)) wall.setWidth(3) wall.setOutline('#303000') wall.draw(window) # -- create and draw the ball ball = Circle(Point(x,y), ball_radius) ball.setOutline('black') ball.setFill(ball_color) ball.draw(window) # -- create timer at top left of window format = " t = %5.2f\n x = %5.2f\n y = %5.2f" timer_position = Point(window_margin, window_top) timer = Text(timer_position, (format % (time, x, y))) timer.setFace('courier') # fixed width, for number alignment timer.draw(window) # -- print text telling the user to click; wait for click to start message_position = Point(window_right/2, -window_margin/2) message = Text(message_position, "Click mouse to start.") message.draw(window) window.getMouse() # -- loop over the time variable, updating position and velocity for tick in range(int(stop_time/dt)): sleep(wait_time) dx = Vx * dt dy = Vy * dt x = x + dx y = y + dy time = time + dt Vy = Vy + g * dt # g is negative, so Vy decreases over time. ball.move(dx, dy) timer.setText(format % (time, x, y)) # --wait for user click before quitting message.setText("Done. Click mouse to quit.") window.getMouse()