Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It looks like you're trying to do an Euler algorithm and getting a bit mixed up in the looping. Here's how I think it should look (and I'll assume this is for a game and not homework... if it is for homework you should state that clearly so we don't give the full answer, like I'm doing here.)</p> <p>This example is for a ball on a spring, which I think you're aiming for. I'm the example, my initial conditions are to thrown diagonally along the x-z axis, and I've also included gravity (if you didn't intend to you vectors you can just replace all the vector quantities with scalars, e.g. t, x, v = 0., 0., 2.; etc).</p> <pre><code>from numpy import * # set the start conditions, etc. n_timesteps = 100 dt, m, k = .1, 1., 2. # timestep, mass, spring-const (I'll write the equations correctly so the units make sense) t, x, v = 0., array([0.,0.,0.]), array([2., 0., 2.]) # initial values gravity = array([0., 0., -9.8]) # to make the problem a little more interesting result = zeros((4, n_timesteps)) # run the simulation, looping through the timesteps for n in range(n_timesteps): # do the calculation f = -k*x + gravity a = f/m v += a*dt x += v*dt # store the results t += dt # just for easy record keeping result[0,n] = t result[1:4, n] = x </code></pre> <p>Note that for loop is looping over the timesteps (and the all looping over the vectors is handles by numpy broadcasting, e.g. f = -k*x+gravity, what could be easier?). Also note that the force is set first, and then we work our way down the chain of integrating the derivatives, then go back to the top and start at the force again. (You're right that this is a bit asymmetric, and really we should update them all at the same time, or something like that, and this is a deficiency of the Euler method, but it works well enough for small timesteps.)</p> <p>Here's what the plots look like... the ball oscillates as expected <a href="http://i36.tinypic.com/zm1hxg.png" rel="nofollow noreferrer">alt text http://i36.tinypic.com/zm1hxg.png</a></p> <p><strong>Edit</strong>: To clarify your question: Basically, your code's issue is not a question of "starting the functions" as you imply; instead your code is approaching the problem in the wrong way, so you need to fix the approach. It looks like you're trying to iterate your timesteps <em>within</em> each function. <em>This is incorrect!</em> Instead you need to do an <em>enveloping iteration</em> through the timesteps, and for each timestep, update the <em>current</em> state of each variable used in the calculation <em>at that timestep</em>. You can write this update as a separate function or, for example, you can do it inline like I did. But it makes no sense to iterate the timesteps within each variable calculation function. Instead, for your example to make sense, <code>force</code>, <code>velocity</code>, and other functions should have as inputs things at the present timestep and return an update to the state of that variable to be used in the next timestep. See how my example does this: it just cycles through the timesteps and <em>within</em> each timestep cycle it sequentially updates all the variables, basing each updated variable on the variables that were updated just before it <em>in this current timestep</em>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload