Home > other >  Loop inside of a loop in Python
Loop inside of a loop in Python

Time:11-09

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
  • Related