TRAER.PHYSICS 3.0


A simple particle system physics engine for processing. I've designed this to be application / domain agnostic. All this is supposed to do is let you make particles, apply forces and calculate the positions of particles over time in real-time. Anything else you need to handle yourself. 


There are four parts

  1. ParticleSystem - takes care of gravity, drag, making particles, applying forces and advancing the simulation
  2. Particles - they move around in 3D space based on forces you've applied to them
  3. Springs - they act on two particles
  4. Attractions - which also act on two particles

New Features

Changes since the previous version

DOWNLOAD LIBRARY + SOURCE


LICENSE - Use this code for whatever you want, just send me a link jeff@traer.cc



EXAMPLES


Simple Pendulum

Bouncy Balls

Cloth

Cloud

Random Arboretum

Tendrils

Box



DOCS


PARTICLE SYSTEM


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()

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. You can make as many of these as you'd like per sketch as long as forces from one system don't refer to particles from another. I don't know what would happen if you connected particles from one system to another.


void setIntegrator( int integrator )

pass this either:  ParticleSystem.RUNGE_KUTTA or ParticleSystem.MODIFIED_EULER Runge-Kutta is the default. It takes about 4 times as many cycles as Modified Euler. In return the system gets very stable. If you plan to have have over 1000 particles interacting with each other try Modified Euler. If you will have fewer particles and want tight springs and quicker responses use Runge-Kutta. Stick with the default and if things get slow try switching to Euler. You may have to add more drag or reduce the strength of springs and attractions to keep it stable. The example Random Arboretum above has sections of code you can uncomment to experiment with this.


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. You probably want the magnitude of this to be in the range of 0-5.


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.


void clear()

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


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 is a new particle with mass 1.0 at (0, 0, 0).


int numberOfParticles()

Particle getParticle( int index )

void removeParticle( int index )

void removeParticle( Particle p )

Note removing things shifts the indices and the library does not take responsibility for you deleting particles that forces refer to. e.g. if you have a spring between two particles and remove one things will definitely break. 


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.


int numberOfSprings()

Spring getSpring( int index )

void removeSpring( int index )

void removeSpring( Spring s )

Note removing things shifts the indices.


Attraction makeAttraction( Particle a, Particle b, float strength, float minimumDistance )

Make an attraction (or repulsion) force between two particles. If the strength 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.


int numberOfAttractions()

Attraction getAttraction( int index )

void removeAttraction( int index )

void removeAttraction( Attraction a )

Note removing things shifts the indices.



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
  5. Fixed / Free

void positon().set( float x, float y, float z )

Move the particle to some 3D location.


void position().add( float x, float y, float z );

Move the particle by some 3D amount


float position().x() 

float position().y() 

float position().z()

This is how you get to the dimensions of particle position.


void velocity().set( 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 velocity().add 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.


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.

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 - the force does not get stronger closer than this

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()



CUSTOM FORCES


Each particle has a Vector3D called force. If you make your own subclass of Force you can stick it in the particle system and have it applied along with all the other forces. The relevant methods from ParticleSystem are: 


void addCustomForce( Force f )

Force getCustomForce( int index )

int numberOfCustomForces()

void removeCustomForce( int index )

void removeCustomForce( Force f )


Example


public class MyCustomForce implements Force

{

// Particle p; or one or more particles

// you're applying this force to


public void apply()

{

// calculate force to apply to particle(s) 

// based on their position and velocity

// e.g. float f = p.position().x();

// add that force to the particle's force vector 

// e.g. p.force().add( f, f, f );

}

}


Then in setup() do something like


physics.addCustomForce( new MyCustomForce( p ) );


p.force() is an instance of Vector3D (just like position and velocity). It has all sorts of facilities like multiplication and dot products that you may want to use. Have a look at the source and how it's used in Spring and Attraction for inspiration.


If you have a good example of a custom force of some kind drop me a line and I'll put it up for others.