Toxiclibs and VerletPhysics

(This is a work-in-progress excerpt from what will hopefully be my upcoming Nature of Code book.)

   

View online examples: Simple Two Particles and a Spring, Chain (soft pendulum), Force Directed Graph

Download examples: toxiclibs.zip

Toxiclibs site: http://toxiclibs.org/
Download Toxiclibs: http://toxiclibs.org/downloads/

Toxiclibs

From the toxiclibs web site:

Toxiclibs toxiclibs is an independent, open source library collection for computational design tasks with Java & Processing developed by Karsten “toxi” Schmidt (thus far). The classes are purposefully kept fairly generic in order to maximize re-use in different contexts ranging from generative design, animation, interaction/interface design, data visualization to architecture and digital fabrication, use as teaching tool and more.

Toxiclibs is separated into seven different libraries that help with various tasks from color theory to spatial audio. For the purposes of this tutorial we’re going to look at only two of these libraries:

  • toxi.geom: set of classes for vector math, geometry, matrices, etc.
  • toxi.physics: 2D & 3D particle physics engine with Verlet integration

VerletPhysics

Verlet Integration is a fancy sounding term that you may have heard bandied about in computational media circles. To understand it, we need only turn to our basic motion algorithm:

  • location changes according to velocity
  • velocity changes according to acceleration

With the above algorithm, we took care to store our velocity as a PVector. Nevertheless, we don’t actually need to store velocity. If we know the previous location of an object, we can dynamically calculate velocity as the difference between current location and previous location. This is the driving principle behind Verlet Integration, but for a more a detailed description, visit http://www.teknikus.dk/tj/gdc2001.htm.

In toxiclibs, a VerletPhysics world is a physics engine that employs the above technique. Particles and springs (which act as joints between particles) can live in within the physics world. The world also has gravity and friction (both customizable) as well as an optional axis-aligned bounding box (AABB). The VerletPhysics engine works both in 3D (VerletPhysics) and 2D (VerletPhysics2D)

Here’s an example of setting up a Verlet physics world in 2D:

  VerletPhysics2D physics=new VerletPhysics2D();
  physics.addBehavior(new GravityBehavior(new Vec2D(0,0.5)));
 
  // This is the center of the world
  Vec2D center = new Vec2D(width/2,height/2);
  // these are the worlds dimensions (50%, a vector pointing out from the center in both directions)
  Vec2D extent = new Vec2D(width/2,height/2);
 
  // Set the world's bounding box
  physics.setWorldBounds(Rect.fromCenterExtent(center,extent));

Using Inheritance

In the Box2D tutorial, we saw how we can create our own class (called, say, Particle) and include a reference to a Box2D Body. While this was somewhat redundant since Box2D itself keeps track of all of the bodies in its world, it was very convenient for us since we didn’t have to ask Box2D for the Body reference when it came time to draw the object.

However, if you take a look at the particle system tutorial, you may have noticed a hint at another technique we can use — inheritance. Let’s consider the class VerletParticle in toxiclibs. We know we want to make our own Particle class so that we can draw our particle a certain way and include any custom properties. Using the technique we saw in Box2D, we’d probably write our code as follows:

class Particle {
  VerletParticle2D p;
 
  Particle(Vec2D pos) {
    p = new VerletParticle2D(pos);
  }
 
  void display() {
    fill(0,150); 
    stroke(0);
    ellipse(p.x,p.y,16,16);
  }
}

But why bother making a VerletParticle inside a Particle when we can simply extend VerletParticle? (We’ll see a nice payoff for this technique when we go to make VerletSpring objects.)

class Particle extends VerletParticle2D {
 
  Particle(float x, float y) {
    super(x,y);
  }
 
  void display() {
    fill(175);
    stroke(0);
    ellipse(x,y,16,16);
  }
}

With the above, we can now make our own custom Particle objects.

Particle p1 = new Particle(100,20);
Particle p2 = new Particle(100,180); 
 
// Anything we make, we have to add into the physics world
physics.addParticle(p1);
physics.addParticle(p2);

Springs

One of the more useful aspects of toxiclibs VerletPhysics library is its Spring classes, these include:

VerletSpring: This class creates a springy connection between two VerletParticles in space. A Spring’s properties can be configured in such a way as to create a stiff stick-like connection or a highly elastic stretchy connection. A particle can also be locked so that only one end of the Spring can move.

VerletConstrainedSpring: A VerletConstrainedSpring is a spring whose maximum relaxation distance can be limited. This can help to achieve better stability of the whole spring system.

VerletMinDistanceSpring: A VerletMinDistanceSpring is a Spring which only enforces its rest length if the current distance is less than its rest length. This is handy if you want to ensure objects are at least a certain distance from each other, but don’t care if it’s bigger than the enforced minimum.

The inheritance technique we employed above proves to be very useful when creating VerletSprings. VerletSpring, for example, expects two VerletParticles to be passed in when the spring is created. Because the Particle class extends VerletParticle, VerletSpring will accept Particles passed into the constructor! For example:

float len = 80;
float strength = 0.01;
 
Particle p1 = new Particle(100,20);
Particle p2 = new Particle(100,20);
VerletSpring2D spring=new VerletSpring2D(p1,p2,80,0.01);

Just like with particles, springs also have to be added to the physics world:

physics.addSpring(spring);

Putting everything together, we have a simple two particles and spring example:

import toxi.physics2d.*;
import toxi.physics2d.behaviors.*;
import toxi.geom.*;
 
// Reference to physics world
VerletPhysics2D physics;
 
Particle p1;
Particle p2;
 
void setup() {
  size(200,200);
  smooth();
  frameRate(30);
 
  // Initialize the physics
  physics=new VerletPhysics2D();
  physics.addBehavior(new GravityBehavior(new Vec2D(0,0.5)));
 
  // This is the center of the world
  Vec2D center = new Vec2D(width/2,height/2);
  // these are the worlds dimensions (50%, a vector pointing out from the center in both directions)
  Vec2D extent = new Vec2D(width/2,height/2);
 
  // Set the world's bounding box
  physics.setWorldBounds(Rect.fromCenterExtent(center,extent));
 
  // Make two particles
  p1 = new Particle(100,20);
  p2 = new Particle(100,180);
  // Lock one in place
  p1.lock();
 
  // Make a spring connecting both Particles
  VerletSpring2D spring=new VerletSpring2D(p1,p2,80,0.01);
 
  // Anything we make, we have to add into the physics world
  physics.addParticle(p1);
  physics.addParticle(p2);
  physics.addSpring(spring);
}
 
void draw() {
 
  // Update the physics world
  physics.update();
 
  background(255);
 
  // Draw a line between the particles
  line(p1.x,p1.y,p2.x,p2.y);
 
  // Display the particles
  p1.display();
  p2.display();
}
  • alphachap

    Just downloaded toxiclibs-complete-0020.zip
    Unzipped and installed in my sketchbook libraries folder.
    Downloaded examples toxiclibs.zip from http://www.shiffman.net/teaching/nature/toxiclibs/

    I ran ChainDemo.pde and got the error message:
    The function setGravity(vec2D) does not exist.

    // Initialize the physics world
    physics=new VerletPhysics2D(); <<<<<<<< HERE
    physics.setGravity(new Vec2D(0,0.1));
    physics.setWorldBounds(new Rect(0,0,width,height));

    So what now?

    PS: The toxiclibs subfolder of my sketchbook libraries folder is named: "toxiclibs-complete-0020"
    Is that a problem? or should I rename it "toxiclibs"?

    Thanks

  • http://www.shiffman.net Daniel

    Oh, I’m going to have to update my examples to be compatible with the new version of toxiclibs! You can find the example in toxi’s download under Shiffmann_Chain, but here is the new code you’ll need:

    At top:

    import toxi.physics2d.behaviors.*;
    

    In setup():

      physics.addBehavior(new GravityBehavior(new Vec2D(0,0.1)));
    

    UPDATE: examples are compatible with 0020 now

  • http://profiles.google.com/rascal86 Pawe? ?ak

    Hello,

    I’ve run your example of force directed layout with toxiclibs but its performance is around 10 fps. Why is it so low? It’s not large graph. I’ve tried it on different computers with similar result.

    Thanks

  • Anonymous

    I don’t have this problem (Processing 1.5, toxiclibs 00020, mac os x 10.6). What versions / OS are you using?

  • Veryphatic

    Hi Daniel, thanks for this tutorial. It is a most excellent introduction to Verlet physics in Toxiclibs :)

    I found the link to Teknikus to be broken, but there are a couple of copies floating around, most notably at http://classic-web.archive.org/web/20080822161636/http://www.teknikus.dk/tj/gdc2001.htm

    Thanks again :)

  • Monir_karimi

    hi daniel where can i find noc library?

  • Anonymous

    Where do you see a reference to the NOC library?  That was an old library and has been replaced by PVector that is built into processing.  If you are looking for toxiclibs: http://toxiclibs.org/