December 4th, 2012, 09:42 AM

Help a physics student? :)
Hello all, I am trying to write a simple script to visualize the trajectory of a soccer ball using python (for an extra credit assignment in my mechanics class). I am very familiar with Java, C++ and VB, but not so much with python, especially visual stuff. I'm hoping you all can help!
I've got the following script which plots the trajectory of the ball beautifully. However, the ball hits the "earth" (z axis = 0), and keeps going. My thoughts are that I could change this behavior using a while loop. Like, while z >= 0, plot the trajectory.
Then, change the vertical velocity from its current negative value to a positive value (making the ball "bounce").
Then run another while loop... I could have 3 while loops for 3 bounces. It doesn't need to be an efficient program (this isn't a CS class), it just needs to work.
Here's my script:
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
mpl.rcParams['legend.fontsize'] = 10
fig = plt.figure()
ax = fig.gca(projection='3d')
### Define Variables ###
time = (10) #Time to calculate the equations
t = np.linspace(0, time, 100)
g = (9.81) #Gravity
vxo = (3) #initial velocity in the xdirection
vyo = (1) #initial velocity in the ydirection
vzo = (15) #initial velocity in the zdirection
xo = (0) #initial xposition
yo = (0) #initial yposition
zo = (0) #initial zposition
### Equations of Motion ###
x = (xo + (vxo * t))
y = (yo + (vyo * t))
z = (zo + (vzo * t) + (.5 * g * (t**2)))
#Here is where I am thinking I need to insert a while loop??
#While (z >= 0):
ax.plot(x, y, z, label=('Trajectory of Soccer Ball ' + str(time)))
ax.legend()
#Then flip the sign on the vertical velocity:
#vzo = (1 * vzo)
#then continue to plot now that the ball is moving back UP
### Set axis limits ###
ax.set_xlim3d(0,10)
ax.set_ylim3d(0,10)
ax.set_zlim3d(0,10)
plt.show()
December 4th, 2012, 09:57 AM

I don't know anything about matplotlib or numpy but maybe I can help with the loop. Let's say you have (as you do appear to) the correct eq of motion for some time period: t=0100, for instance, with an interval of 1 (just to make it convenient). This could be seconds, fortnights, or any units of time as long as they are the independent variable in the equations. Now, somewhere in your code, either matplotlib or numpy or something is doing the time loop for you but I don't know where so let's put it out there:
Code:
for t in xrange(100): #that samples t from 0 to 100 at dt=1
x,y,z=AnotherFunction(t,xdot,ydot,zdot,x,y,z) #your eq's of motion in this function
if z<0:
zdot=zdot
else: <plot>
This should bounce as many times as it needs to within the timeframe
December 4th, 2012, 10:17 AM

I like that, it helps simplify things. Now I need to figure out how to make it work with numpy and matplotlib...
It would seem that my variables x, y, and z are actually treated like arrays (time in one column, and position in the other)
For instance,
z:
0,0
1,1
2,4
3,7
4,12
So you can see time increasing steadily in one column, and the position is being calculated by the equation of motion. THEN the program plots these values.
If I can somehow deconstruct how this is happening, I can more intelligently manipulate it... Any ideas there?
December 4th, 2012, 12:06 PM

time is a vector, all the solutions are vectors. You don't need a "while loop"
You could install the statement
z = abs(z)
right before your comment
#Here is where I am thinking I need to insert a while loop??
Well, that's completely *!&%ed up because the velocity should change sign nonlinearly, and the new parabola should be concave down.
I'd integrate the equations of motion. http://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.odeint.html with a velocity function that checks the height. Using the ode you could install realistic drag and bounce friction.
Much faster if you don't care about the drag and solve the equations piecewise. You might consider learning how to index arrays or the numpy.concatenate function.
[code]
Code tags[/code] are essential for python code and Makefiles!
December 4th, 2012, 01:59 PM

I got it; it just took some clever thinking.
Here's what I got, using nested for loops:
Code:
for i in range(0,fineness):
if z[i] < 0:
zvo = (zv[i])
for j in range(i,fineness):
z[j] = ((zvo * t[(ji)]) + (.5 * g * (t[(ji)]**2)))
v[j] = (zvo + (g*t[(ji)]))
fineness is a variable I use to control how many samples are taken in the time range specified. So, from t 0 to 10, I could have 10 samples (very inaccurate) or 1000 samples (much more accurate).
Basically, I first calculate the value of Z from t = 0 to 10. Then, I have this for loop test to see if one particular value of Z has gone below 0. If it has, the CURRENT velocity in the Z direction is set to a positive value, and used as the INITIAL velocity in the Z direction going forward.
The nested For loop rewrites every value of the position array Z from the moment it went sub0 to the end of the time range. It will rewrite it as many times as necessary to cover the time range (so possible a few times).
I know this method isn't perfect or pretty, and it would get some marks down for unnecessary repetitiveness from a CS prof, but this is going to my physics prof who could care less, as long as it works. With my machine, it takes a fraction of a second to calculate, so that's fine with me.
December 4th, 2012, 02:23 PM

I'm glad it's solved. If you index items one at a time numpy provides little benefit.
[code]
Code tags[/code] are essential for python code and Makefiles!