Force-driven particles

by Bad Sector of Nasty Bugs

Hello, world. This is another "just done, let's write something about" tutorial. Some days ago, I was in Athens and talked with Outsider of Quadra about an idea that had come in my mind. It was about how to use force-driven particles (and force-driven objects that rely on xyz coordinates). When I presented him my idea, he simply said "then do it". And so I did. Here I'll explain with a few words what I did.

From the school we know (?) that forces are actually vectors. So, when we have a particle, we just can "drive" it using vectors like:

particle.x += particle.force.x;
particle.y += particle.force.y;
particle.z += particle.force.z;

particle.force is a vector that contains a xyz value. If you want to have gravity, just use the following:

particle.x += particle.force.x;
particle.y += particle.force.y+gravity;
particle.z += particle.force.z;

where gravity is a constant value. Good values for gravity range from 0 to 1 (0.4 is a good one). However, it depends on your metrics system.

If you want to put more than one force, just add the vectors:

particle.force.x += force.x;
particle.force.y += force.y;
particle.force.z += force.z;

(If you are using C++ or another object-oriented language, you can define a "putForce" function that does that - it's handy. You can also do that with C by using a pointer to a struct as the function's parameter.)

In order to emulate the behaviour of the friction between air and the particle, decrease the value of the force like:

particle.force.x *= 0.995;
particle.force.y *= 0.995;
particle.force.z *= 0.995;

This will "slow down" the particle after some time (you don't need to do that if your particles are in the space). If you don't add this, the movement will look somehow unnatural because the particle will move forever. Note that 0.995 is a random value that I invented myself. You can use any value, but don't overdo it. :-)

Now, in the HUGI bonus pack, you'll found FORCES1.BAS, a little program I wrote in QBasic in order to test the explanations above (I used QBasic because I was too lazy to initialize DirectDraw, GDI, or whatever else is needed under Windows and C/C++ ;-).

Bad Sector / Nasty Bugs