Putting the Bounce Back in my Bungie
Now, gravity was a pretty obvious force to apply to particles. But what else can I do? A loose connection of points isn’t really all that interesting to watch even if it is simulated with accurate physics. It would be much more entertaining if I could connect those particles to form structures.
What about stretching a spring between two particles? This procedure is actually easy to implement. Hook’s spring law is a pretty good way of representing the forces that a spring exerts on two points:
This formula represents the force applied to particles a and b; the distance between these particles, L; the rest length of the spring, r; the spring constant or "stiffness", ks; the damping constant, kd; and the velocity of the particles, v. The damping term in the equation is needed in order to simulate the natural damping that would occur due to the forces of friction. This force, called viscous damping, is the friction force exerted on a system that is directly proportional and opposite to the velocity of the moving mass. In practice, the damping term lends stability to the action of the spring. The code applying the spring force on two particles is in Listing 3.
Listing 3. A damped spring force.
p1 = &system[spring->p1];
p2 = &system[spring->p2];
VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance
dist = VectorLength(&deltaP); // Magnitude of deltaP
Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest)
Delta Velocity Vector
Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term
/ dist, &springForce); // Normalize Distance Vector
ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force
VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1
VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2
Viscous drag should be applied to the entire system. A drag is a great way of making the particles look as though they are floating around in oil. It also adds numerical stability to the system, meaning that the particles won’t bounce around too much. A viscous drag force is applied by multiplying a damping constant, Kd, with the velocity of the particle and subtracting that force from the accumulator.
Momentary forces are also very useful for interacting with the simulation. I’ve used a spring tied to a particle and attached the mouse to drag the object around. A force applied to a particle can be used to create a motor or other source of motion.
You can also make some interesting effects by locking a particle. That is, by turning off the simulation for a particular particle, it becomes fixed and can act as an anchor point. (You can achieve the same effect by causing the particle to have an infinite mass. In the simulator, simply set the particle’s mass to zero.) Immobilizing one particle like this creates many possibilities for creating complex simulations.
Finally, Back to Collision
Whew, now that I have a nice dynamic particle simulator, I can start talking about collision detection and response again. The simplest form of collision detection that I can add to this simulation is point-to-plane collision. With particles, it will be easy. Last month, I discussed the use of the dot product to determine whether a point has collided with a plane. Take a look at Figure 1.
Figure 1. A particle colliding with a plane.
Particle X with a velocity vector V is moving towards plane P with a normal N. I know that a collision of some sort occurred if (X-P) • N < e, where e is some small threshold near zero. If that value is < -e, then the particle has passed through the wall, penetrating it. That won’t make my simulator happy, so if a particle is penetrating any boundary, it’s necessary to back up the simulator a little and try again. If the dot product is just very near zero, then I have what is called a contact and I need to check further.
A particle in contact with a boundary may not be colliding with that boundary if the particle is moving away from the boundary. The relative velocity of the two bodies is checked by calculating N • V. If that value is less than zero, the two bodies are in colliding contact and I need to resolve the collision.
Figure 2. Components of
To resolve the collision, I need to calculate two more vectors. They represent the motion parallel and tangential to the normal of collision. Take a look at Figure 2.The normal of collision is simply the normal to the plane. I calculate the velocity after the collision with this equation:
In this equation, Kr is the coefficient of restitution. This is the amount of the normal force, Vn, that is applied to the resulting force. If Kr is 1, I have a totally elastic collision. If it is 0, the particle sticks to the plane.