In this lab we will try to establish the relationship between the angle an object is thrown and the distance it will travel under the influence of gravity before hitting the ground. Assume the object is always thrown with the same speed but a varying angle with respect to the ground. This is a 2-dimensional problem so we'll need to get our programs to work in the 2D case. Looking only at the vertical direction will establish how long it will take for the object to reach the ground. Using that value for time, we can use an expression for the distance traveled along the ground in that time since we know there is no acceleration in the x direction. We can view the displacement in the x direction as simple uniform motion (acceleration in x direction=0).
Each step in the lab asks you to add new capability to the same program. Turn in your final program and a table of values computed as described in the final step. If you are unable to get the program working properly, turn in what you have so far on the due date so we can figure out where you need help.
Lets start with the solution to one of last week's problems--the program which uses the analytical solution to the uniform acceleration problem to plot displacement over a period of time.
from visual.graph import * x0 = 0 # starting position v0 = 5 # v is velocity in m/s a = -1 # a is the acceleration in m/s/s t = 0 # starting time in seconds dt = 1 # delta t, the change in time def displacement(t): return x0 + v0*t + a*t*t/2.0 graph = gdisplay() curve = gcurve() # For a slightly fancier graph replace the above lines with these: #graph = gdisplay(title="Uniform Acceleration", xtitle="displacement", ytitle="time") #curve = gcurve(color=(1,1,0)) while t<=20 : x = displacement(t) print t,x curve.plot(pos=(t,x)) t = t+dt
First modify this program so the loop will continue for as much
time as necessary until the particle reaches the ground
(displacement=0). To make things a bit clearer, change x
to y
since we are initially interested in the
displacement in the y direction. Lets use a smaller Δt for
better accuracy. Choosing .125 (which is 1/8) will prevent the strange
round off errors in our time variable since 1/8 can be represented
exactly in binary as .0012. Still we
will only be able to estimate the time our particle hit the ground to
the nearest 1/8th of a second.
Now we need to make the program work for 2-dimensional
problems. Well represent 2D vectors like 2i+3j as 2-element lists like
this: [2,3]
. So initial position, x0
, should
become an initial position vector: p0 = [0,0]
. Similarly, the
initial velocity and the constant acceleration due to gravity become
vector quantities. Now the displacement()
function should
return a vector as well. See this vector normalize function as an example
of a function which takes a vector as an argument and returns a
vector. Verify that the program still computes the same result after
the new changes.
To see the relationship between angle and distance traveled, we need to be able to specify the initial velocity of our
particle in terms of speed and angle with respect to horizontal (of a ball leaving the hand,
a cannonball leaving the barrel, etc.) Since we are trying to find the
relationship between the distance traveled and the angle the particle
leaves the ground, we want to keep speed constant and sweep the angle
through a number of evenly spaced values. We need another function
called polar2rect()
that will use trigonometry to take speed and an angle as
inputs and return a vector. Try giving a particle an initial speed of
50m/s thrown at an angle of 45° up from horizontal and with
gravity set to standard 9.8m/s2 downwards. If your code is working right, it
should print out a distance of 256.33m in 7.25 seconds.
Add code to graph the trajectory of the particle in a
gdisplay
window. Don't plot displacement versus
time, plot the position vector x versus y.
Now put a for loop around the simulation to rerun the experiment
for a range of initial angles from 0 to 180 degrees in 5 degree
steps. Plot each new trajectory with a new gcurve()
on
the graph and print out a table of values showing the final
displacement and the time aloft.
Finally, make a second plot window which shows a graph with the angle the object was thrown on the x axis and the distance attained on the y axis. What is the shape of the graph? Do you recognize the function?
This solution color codes each trajectory curve so that the
corresponding segment in the angle vs. displacement curve is the same color.
The math
library's radian()
function was used
to convert angles from degrees to radians.
from visual.graph import * speed=50 # initial speed p0 = [0,0] # initial position a = [0,-9.8] # acceleration due to gravity dt=.125 # time increment def displacement(t,x0=[0,0],v0=[0,0],a=[0,0]): 'compute 2D vector displacement of a particle undergoing uniform acceleration' x = x0[0] + v0[0]*t + 0.5*a[0]*t*t y = x0[1] + v0[1]*t + 0.5*a[1]*t*t return [x,y] def polar2rect(r,theta): 'convert a polar vector to rectangular representation' return [r*cos(theta), r*sin(theta)] #graph of the path particles with different initial angles pathgraph = gdisplay(title="Trajectory",xmin=-260,xmax=260,ymax=130) #graph of the angle versus distance final displacement distgraph = gdisplay(title="Angle vs Distance",xtitle="theta",ytitle="distance", xmax=180,ymin=-260,ymax=260) distcurve = gcurve(gdisplay=distgraph) print "angle (degrees) | disp (m) | time (s)" #print heading of table of data for angle in range(0,185,5): theta = radians(angle) # compute angle in radians, call it theta #plot curves with gratuitous colors to impress management red = max(0,cos(theta)) green = sin(theta) blue = max(0,cos(pi+theta)) curve = gcurve(gdisplay=pathgraph, color=(red,green,blue)) # reset variables to initial values p = p0 v0 = polar2rect(speed,theta) t = 0 curve.plot(pos=p) # plot starting position # run simulation for one angle while p[1]>=0: t+=dt p=displacement(t,p0,v0,a) curve.plot(pos=p) # plot final final position versus angle and print it distcurve.plot(pos=(angle,p[0]),color=(red,green,blue)) print " %3d | %8.2f | %7.3f" % (angle,p[0],t)