The below is code for the modelling of a cannoball's movement with drag, where solve_euler is a predefined function, that produces an array of arrays (like a table) of values. Of these values the xs and the ys are exported for this bit of code and are called xs_euler and ys_euler. These values are the x and y coordinates of the cannonball until time t1 (some defined number used in the solve_euler function, in this case t1 = 300). What I am trying to now do, is plot a graph of the new x and y values (by multiplying by velocity and time), showing how the paths differ depending on the launch angle. The following is what I have at the moment:
import math as m
import matplotlib.pylab as plot
import numpy
n_steps = 1000
theta = numpy.arange(m.pi/36, m.pi/2, m.pi/36)
v = 200
g = 9.81
initial_conditions = [0, 0, 88.38834764831843, 88.38834764831843]
values_euler = solve_euler(initial_conditions, 300, n_steps)
xs_euler, ys_euler = values_euler[:,0], values_euler[:,1]
plt.plot(xs_euler, ys_euler, color='blue', linestyle='--')
plt.xlim(0,1500)
plt.ylim(0,800);
t = numpy.linspace(0, 500, num=1000) # Set time as 'continous' parameter.
for i in theta: # Calculate trajectory for every angle
for k in t:
x = ((v*k)*xs_euler*numpy.cos(i)) # get positions at every point in time
y = ((v*k)*ys_euler*numpy.sin(i))-((0.5*g)*(k**2))
plot.plot(x1, y1) # Plot for every angle
plot.show() # And show on one graphic
Here it should be pretty obvious that I don't know how to use xs_euler and the ys_euler, in the loop, whilst also being able to do a loop on the time and on the launch angle (theta). Can someone show me where I am going wrong and how to fix it?
CodePudding user response:
I'm assuming you want your graphs to be y(t) vs x(t) for all time points, in that case you will need to store all values of x and y over time while iterating for each theta:
My suggestion would be to create a list of the x and y values for a given theta, iterating over time. This can be written with list comprehension to overwrite for each value of i, if you don't need to store it. If you do, I would just write it to columns of a dataframe.
And another thing that I am slightly confused by is your plot is called "plt" in some instances and "plot" in others. I would recommend keeping it consistent with how you import it (which is as "plot" in import matplotlib.pylab as plot
)
for i in theta: # Calculate trajectory for every angle
x = [((v*k)*xs_euler*numpy.cos(i)) for k in t] # get positions at every point in time
y = [((v*k)*ys_euler*numpy.sin(i))-((0.5*g)*(k**2)) for k in t]
plot.plot(x, y) # Plot for every angle
plot.show()
CodePudding user response:
Your problem isn't with coding, it's with the math.
Unless I'm not understanding what solve_euler
is, you shouldn't need to modify xs_euler
or ys_euler
, those are already the x and y coordinates of the ball at different points in time. BUT the solve_euler
function only returns data for ONE initial condition - meaning if you want data for a different initial angle, you need to call it again (You can't use data from one initial condition to calculate trajectories of a different initial condition. This system doesn't work that way - almost no systems do).
So you have to iterate through angles and call solve_euler
each time, and plot the data that it returns.
Some pseudocode:
create matplotlib figure, set all axes and whatnot
for angle-you-want-to-iterate-through:
vx0 = x-component of initial velocity (will have a cos(angle))
vy0 = y-component of initial velocity (will have a sin(angle))
initial conditions are [x0, y0, vx0, vy0]
data = result of solve_euler with the new initial conditions
plot data[:0] vs data[:1], label with angle
add a legend to plot