Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / Game Design & Programming / Verlet integration and timestep question Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
arctwelve

January 10, 2005, 04:28 PM


I'm trying to implement Verlet integration as described in Jakobsen's paper. I noticed something odd when I changed the timestep value in the integrator: not just the speed changed, but also the motion of my particle.

To set my particle in motion I set it's current position slighly different than its previous position, as described in the article. Let's say in 2D I set the previous pos lower and to the left of the current pos. Then the particle moves in an upward arc to the right. At lower timesteps the arc it travels is longer.

Is this supposed to happen? When I use euler Im used to changes in speed (and accuracy) but the motion remains fairly consistent.

 
John Schultz

January 10, 2005, 05:15 PM

arctwelve wrote: I'm trying to implement Verlet integration as described in Jakobsen's paper. I noticed something odd when I changed the timestep value in the integrator: not just the speed changed, but also the motion of my particle. To set my particle in motion I set it's current position slighly different than its previous position, as described in the article. Let's say in 2D I set the previous pos lower and to the left of the current pos. Then the particle moves in an upward arc to the right. At lower timesteps the arc it travels is longer. Is this supposed to happen? When I use euler Im used to changes in speed (and accuracy) but the motion remains fairly consistent.


No, that should not happen.

There are two places to set time values with (velocity-less) Verlet: the time value used in updating forces=>acceleration (dt squared), and the time value used to update the simulation loop.

1. Use a fixed timestep: update the simulation N times between graphic updates. Keep track of the delta-time remainder (since you can only perform N integer update counts) for the next physics-graphics loop. You can also run the simulation in a thread at a fixed rate (in Win32, you can use WaitForSingleObject() with an appropriate timeout to wake the thread at the desired rate).
2. Make sure that you update both time values.

You should see little difference in behavior going between (for example) 50-100Hz (springs will show the most change). If you change the time values while running, you should only see a small jump in motion, after which motion should look very similar to the previous timestep.

I performed experiments switching between Euler, RK2 (midpoint,), RK4 (Runge-Kutta), and Verlet. Changing the simulation time did not show a major difference in (basic) motion between the various methods (springs, stiff systems, and high angular velocities show the most (visible) change between integration methods).

 
arctwelve

January 10, 2005, 06:07 PM

Ok, I see why it is happening. When I apply the force of gravity, it is getting scaled by the timestep and causing the particles motion to change. If the time step is higher then gravity gets scaled up and the particle drops quicker.

What am I doing wrong? Below is my integrator code:

  1.  
  2. for (var i = 0; i < this.particles.length; i++) {
  3.                
  4.         var p = this.particles[i];
  5.                
  6.         this.temp.x = p.curr.x;
  7.         this.temp.y = p.curr.y;
  8.                
  9.         p.curr.x = 2 * p.curr.x - p.prev.x + p.forces.x * this.t2;
  10.         p.curr.y = 2 * p.curr.y - p.prev.y + p.forces.y * this.t2;
  11.                
  12.         p.prev.x = this.temp.x;
  13.         p.prev.y = this.temp.y;
  14. }
  15.  
  16.  

 
John Schultz

January 10, 2005, 07:46 PM

At what rate do you call the integration loop? For example, with a 100Hz simulation, you'd call the loop 100 times per second, giving a deltaTime of 1/100. this.t2 would equal 1/100*1/100 = 1/10000.

Try working through a few iterations on paper (or write some test code) and compare the results to a direct computation of x' = x + v*t + .5*a*t*t. For a simple dropping object starting at rest, test with x' = x + .5*a*t*t.

For clarity, you should change p.forces to p.acceleration (your example assumes a mass of 1.0 (since you are not computing acceleration = force/mass). I would also change this.t2 to this.dt2 or this.deltaTime2 (deltaTime squared).

 
arctwelve

January 10, 2005, 10:40 PM



Im calling the timeStep method 60 times a second. The timeStep method then calls

  1.  
  2. accumulateForces();
  3. verlet();
  4. satisfyConstraints();
  5.  


The verlet() function I have uses a member variable deltaTime which is set when the ParticleSystem class is initialized. Ive been setting this value to various numbers (eg, 0.01) to test it, and getting the unexpected results. Am I making a mistake here?

I don't see how acceleration wont be scaled when it is always multiplied by the timestep squared.

Thanks alot for your help.

 
John Schultz

January 10, 2005, 10:52 PM

arctwelve wrote: Im calling the timeStep method 60 times a second. The timeStep method then calls
  1.  
  2. accumulateForces();
  3. verlet();
  4. satisfyConstraints();
  5.  
The verlet() function I have uses a member variable deltaTime which is set when the ParticleSystem class is initialized. Ive been setting this value to various numbers (eg, 0.01) to test it, and getting the unexpected results. Am I making a mistake here? I don't see how acceleration wont be scaled when it is always multiplied by the timestep squared. Thanks alot for your help.


Since your timeStep method runs at 60Hz, deltaTime must be set to 1/60*1/60 = 1/3600. You can't set it to any other value (if you want your integrator to work correctly). Using your variable names:

timeStep = N (your example: 60, simulation update count per second)
deltaTime = 1/(N*N) (your example: 1/3600, delta time squared)

For clarity it should be:
simulationRateInHz = N
deltaTime2 = 1/(simulationRateInHz*simulationRateInHz)

If you want to change the simulation rate, you have to change both numbers.

 
arctwelve

January 11, 2005, 01:41 PM

That clears it up.

Thanks again for your help.

 
This thread contains 7 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.