a particle system physics engine for processing. Just a simulation, it tells you where particles are and it's your job to draw them. No collisions, you can take care of them yourself if you want!

DOWNLOAD traer.physics library for processing, unzip it and put it in /processing/libraries/

There are 4 parts:

  1. The ParticleSystem, which basically takes of care of everything
  2. Particles, which move around in space according to the forces acting on them
  3. Springs, each which acts on 2 particles
  4. Attractions/repulsions, which act on 2 particles

Some features:

  1. A very stable RK4 integrator so you can put lots of complicated forces on things
  2. Fast java implementation and super fast square root
  3. simple destruction of particles that automatically gets rid of any associated forces

Examples

Tips

Stability is always an issue. By stability i mean whether or not the simulation blows up and your particles fly off the screen. Stability is proportional to the forces acting on the particles and the time step. Larger time steps are less stable than smaller ones but many smaller steps require more computation and might slow down your frame rate. At any given time step there is a limit to how much force you can have and still be stable. If you have a really high spring constant the spring will be very stiff and snap back quickly, but maybe too quickly. Maybe it explodes. I used a 4th order Runge-Kutta integrator (or RK4 as it's called) so it is pretty stable and should give you really fast accelerations.

I usually use particles with 1.0 mass and a time step of 1.0 at 24 frames per second. Springs with a spring constant of 0.1 and damping of 0.1 behave pretty springily. Look at the examples, especially the dangly spring to get a feel parameter tweaking.

You can either keep track of the particles and forces yourself in variables or data structures or iterate directly through all the particles and forces in your system. If all your particles represent things on screen (they might not be if one is the mouse or something) then just go through the one in the system. For more complicated stuff you are going to want to make some objects that keep track of some subset of the forces or particles, like in the tendrils example above.

How does all this work?

I started with Andrew Witkin's SIGGRAPH course notes on particle system dynamics. Then i added a much more stable 4th order Runge Kutta solver instead of Euler. The RK4 implementation is pretty analogous to the Euler step, that function f is where you apply your forces each time and then look at the results. The fast, actually inverse, squareroot is originally from John Carmack, i used a slightly different version from Chris Lomont here. You'll also want to check out Dan Shiffman's course The Nature of Code.

ParticleSystem

The particle system is in charge of everything. It makes particles and forces for you and you tell it to advance the simulation using tick().

new ParticleSystem( float gravityY, float drag )
new ParticleSystem( float gx, float gy, float gz, float drag )
Construct a new particle system with some downward (positive y) or 3D gravity and some drag

void setGravity( float y )
void setGravity( float x, float, y, float z )
set the strength of gravity, down (in the positive y direction) or in whatever 3D direction you feel like.

void setDrag( float drag )
set the drag force that acts on all objects equally, and proportional to velocity.

void tick()
void tick( float t )
advance the simulation by some time t, or by the default 1.0. You'll want to call this in draw(). You probably want to keep this the same at all times unless you want speed up or slow things down.

Particle makeParticle()
Particle makeParticle( float mass, float x, float y, float z )
create a new particle in the system with some mass and at some x, y, z position. The default a new particle with mass 1.0 at (0, 0, 0).

Spring makeSpring( Particle a, Particle b, float strength, float damping, float restLength )
make a spring in the system between 2 particles you have previously created. Look at spring down there for what the parameters mean.

Attraction makeAttraction( Particle a, Particle b, float strength, float minimumDistance )
make an attraction (or repulsion) force between two particles. If the strenght is negative they repel each other, if the strength is positive they attract. There is also a minimum distance that limits how strong this force can get close up. See attraction for details.

void clear()
this deletes all the particles and all the forces in the system (except the omni present gravity and drag even if ther are 0).

there are also some facilities for iterating through all the particles and forces in the system:

int numberOfParticles()
Particle getParticle( int index )

int numberOfSprings()
Spring getSpring( int index )

int numberOfAttractions()
Attraction getAttraction( int index )

Particle

Particles can represent objects, corners of 2D or 3D shapes or abstract things that won't even be drawn. Particles have 4 properties:

  1. Mass
  2. Position
  3. Velocity
  4. Age
Particles can also be either fixed or free moving.

void moveTo( float x, float y, float z )
Move the particle to some 3D location.

void moveBy( float x, float y, float z )
Add some 3D vector to the position of the particle.

float position().x()
float position().y()
float position().z()
This is how you get to the dimensions of particle position.

void setVelocity( float x, float y, float z )
Set the velocity to some 3D quantity, maybe use this to send a particle flying off in a particular direction.

void addVelocity( float x, float y, float z )
This adds some 3D quantity to the velocity of the particle. You could maybe use this to speed up or slow down a particle.

float velocity().x()
float velocity().y()
float velocity().z()
This is how you get at the dimensions of the particles velocity.

float mass()
void setMass( float m )
These set and get the mass of the particle. Heavier particles will have more inertia and will accelerate slower. Attraction/repulsion forces will also be stronger for heavier particles. If you aren't doing anything special this will probably be the same for all particles.

void makeFixed()
boolean isFixed()
void makeFree()
boolean isFree()
Particles can either be fixed or free. If they are free they move around and are affected by forces, if they are fixed they stay where they are.

void kill()
boolean isDead()
This is how you destroy a particle. It will be disposed of next time you advance the particle system. Any forces you have acting on this particle will also be removed from the particle system.

float age()
How long the particle has been around. Every time you advance the simulation by t every particle gets a little older by t.

Spring

Springs connect 2 particles and try to keep them a certain distance apart. They have 3 properties:

  1. Rest Length, the spring wants to be at this length and acts on the particles to push or pull them exactly this far apart at all times.
  2. Strength, If they are strong they act like a stick. If they are weak they take a long time to return to their rest length.
  3. Damping, If springs have high damping they don't overshoot and they settle down quickly, with low damping springs oscillate.
Springs can also be turned on or off.

Particle getOneEnd()
Particle getTheOtherEnd()
Return the particles that are on either end of this spring.

float currentLength()
The current length of the spring.

float restLength()
void setRestLength( float l )

float strength()
void setStrength( float s )

float damping()
void setDamping( float s )

void turnOff()
void turnOn()
boolean isOn()
boolean isOff()

Attraction

Attractions or repulsions (negative attraction) act on 2 particles and either constantly pull them together or constantly pull them apart by applying a force to each particle:

    G*m1*m2/d2
in other words the force is is much stronger close up than far away. Attractions/repulsions have 2 properties:
  1. Strength, the G up there.
  2. Minimum Distance, in practice, we are going to want to place a limit on how strong that force can be, otherwise once something gets on top of whatever it's attracted to it's not going to let it go. This limits the distance in calculating the above force, but the force is always acting at all distances.
As always you can turn this force on and off.

float strength()
void setStrength( float s )
Positive strength is attraction negative strength is repulsion.

Particle getOneEnd()
Particle getTheOtherEnd()
Return the particles being attracting or repeling each other.

float minimumDistance()
void setMinimumDistance( float d )
Get and set the minimum distance, which limits how strong the force can get close up.

void turnOff()
void turnOn()
boolean isOn()
boolean isOff()