Physics Sim - simple question

Started by
9 comments, last by grisu 13 years, 3 months ago
Hello,


I have a question regarding this simple Physics-Sim: http://www.christianchabek.at/stuff/PhysicsSim.swf

I try to simulate elastic collision. The physics work fine, but sometimes the spheres get stuck together. If you click the stage, you can turn on the gravity, and it's getting even worse.

The problems I see are:
If two or more spheres stick together, you need a lot of enogh energy to seperate them in one frame.
And the things why they get stuck together is, that if a response on a collision happens, it's possible that a new collision starts, but on a sphere that already has been tested.

How can I deal with this?
This must be a common problem, but I don't know where to start or where to search.

Thanks in advance,
Regards,

Chris
Advertisement
I'm almost certain this is caused by an error in the equation calculating the new impulse of the two balls. If the balls aren't completely separated in one frame, but are moving away from each other, they will stick together. You solve the problem by adding a term, so impulse is only applied if the balls are overlapping *and* are moving towards each other. You find out by adding the velocity vectors of the two balls and project this vector onto the separation vector. This will then return a positive or negative number, depending on how you set it up.

Cheers,
Mike
Quote:Original post by h4tt3n
I'm almost certain this is caused by an error in the equation calculating the new impulse of the two balls. If the balls aren't completely separated in one frame, but are moving away from each other, they will stick together. You solve the problem by adding a term, so impulse is only applied if the balls are overlapping *and* are moving towards each other. You find out by adding the velocity vectors of the two balls and project this vector onto the separation vector. This will then return a positive or negative number, depending on how you set it up.

Cheers,
Mike


Maybe I misunderstood the post, but it's not really true.


If we talk about forces:

Only apply the force if
it's positive (it pushes the balls away from each other)
AND
the balls are overlapping

(so the balls CAN push each other (the force has to be applied), even if they are moving away from each other)

That's enough and works (I used that for my tank simulator's terrain collision)

Well, it's just an approximation though. Id doesn't take the oscillation of the balls after collision into account (because the ball CAN exceed its initial surface).
Well ok, I can't say for sure wether that's it or not. But every time I've seen this behaviour - either in my own or orher peoples simulations - it's caused by not dealing correctly with velocity.
Quote:it's possible that a new collision starts, but on a sphere that already has been tested.

It sounds like you're resolving one collision at a time. You might consider separating collision detection and physics. That is, accumulate all the collision information for each object (an array or vector of positions, normals, penetration depths, etc.) and, after the collision phase, apply physics based on the sum of forces involved in the collisions.

I don't know the details of your physics implementation, but, in general, it may be more successful if you let the physics determine position through velocities and forces, rather than repositioning objects directly (if you do that).

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Thanks for all your replies.
I'm a beginner, so... just learning a lot of stuff.

I didn't seperate the balls first, just applied the new velocity.
Now I collect all collisions and sort them based on the penetration depth, then resolve them by seperating the balls (with a factor based on their mass), then apply the new velocity.

Is this the right way? Or can I do a recursive function here to be sure that there are no collisions left?
Because when the balls are on the ground, with gravity turned on, they start to bounce and move jerky. Some even fall through...

http://www.christianchabek.at/stuff/PhysicsSim.swf

Thanks again :)
As Buckeye suggested: Don't resolve the positions, don't move them out of collision. Just leave them as they are after moving them according to the forces.
They will "try" to move out of the collision by themselves anyway if you calculate the contact forces correctly.

The contact spring force should be a function, that's nearly infinite (a very big value in the simulation), when the contact depth has reached a given value (maybe if depth > ball_radius or something); and zero, if the contact depth is zero, or negative. I can't really help with the function, this would require some not-so-basic statics calculation. I would chose a function that makes the simulation look good.

Something like:
image

This is ONLY viable with fixed timestep simulation.

Notes:

This whole thing means that some balls will always be in collision. But if you think about it: in real life the balls would deform. So they initial sphere surfaces will overlap if they are on top of each other and gravity is applied, just like in this simulation. To simulate the real deformed surfaces, then forget about real time simulation and find a super-computer...

Not to mention that moving out of collision will make the simulation very unstable. Consider a lot of balls in a small space. Some balls will shoot out of some situations, the whole simulation might explode, or the application can even crash if you are not cautious about the iterative solver (that you call recursion).

[Edited by - szecs on December 29, 2010 6:10:23 AM]
Suggested algorithm to try.

Pseudo-code (forces and velocities are 2D vectors - same works for 3D):
while( running ){   set the force for every object to zero - not velocity, just force   // collision phase - DOES NOT RESOLVE ANY COLLISION - just calculate forces   // each collision is based on sphere's current position - don't move the sphere   for( s1=0; s1 < totalNumSpheres-1; s1++ )   {      for( s2=s1; s2 < totalNumSpheres; s2++)      {         if( s1 and s2 overlap )         {            // see szecs suggestion for the force to apply to both bodies            calculate depth of penetration            s1.force += force_based_on_penetration            s2.force += force_based_on_penetration         }      }   }   // put code here to determine (for each sphere) if sphere is penetrating non-sphere objects   // such as side of box or the ground plane   // physics phase - position and velocity determined ONLY by forces on sphere   for( s1=0 s1 < totalNumSpheres; s1++ )   {      accel = (s1.force + gravity)/s1.mass // F=MA so A = F/M      origVel = s1.velocity      newVel = origVel + accel * fixed_time      s1.position = 1/2( origVel + newVel ) * fixed_time      s1.velocity = newVel   }   draw spheres at sphere.position}

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

I played around with this... some questions left.

In my way (with no gravity turned on) the kinetic energy always stays the same (no friction). I'm calculating only the new speeds, based on the formula for a perfect elastic collision.
How could I achieve this when applying force/acceleration?

And, a sudden change in velocity, isnt't this also a form of acceleration, just in a very short period of time? Where's the difference to making a force nearly infinite an applying it to velocity?


With elastic objects, there's no such thing as infinite acceleration. Just very big acceleration.

Try the suggested things (implement them), then come back with questions if you don't like the results. We advised you the things we did for a reason.

Then you can add friction and other stuff, but that's a different story (get the basics done first).

This topic is closed to new replies.

Advertisement