"""
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()
syntax highlighted by Code2HTML, v. 0.93pm6