Processing 05: Physical forces & motion

motion

Introduction: Motion
One of the strongest aspects of the processing environment is the ability through object orientated programming, to control the motion of high populations of objects. An object in space, whether it is in motion or not, is described by essentially two (2) qualities; its position ( expressed as a vector {x,y,z} ) at any given time and its velocity ( its speed and direction expressed as a vector {x,y,z} ). Thus, an object that at rest, has a velocity {0,0,0}. Therefore we can also calculate where the object will be at the next time sample by simply adding its current velocity to its current position – future position = position + velocity. We can also predict where the object will be in the future, by simply scaling the object’s velocity by a given time – future position = position + (velocity * N time steps).

Example 01: A Simple Moving Spot
In the following example we create a simple SPOT class that uses processing’s inbuilt vector library to store both the objects position and its velocity. In the update() funtion within this class, we simply add the velocity to the position every frame. This is actually the same class as our OOP example.

 
/*-------------------------------------------------------------------------------------------------
Object Class
 -------------------------------------------------------------------------------------------------*/
// Our class receives a position, size and 3 values pertaining to its draw colour
class SuperSpot
{
  // *** CLASS VARIABLES ***
  PVector pos, vel, acc;
  float maxVel;
  float sSize;
  int spotCol;
 
  // *** CLASS CONSTRUCTOR ***
  SuperSpot(PVector _POS, float _S){
    pos     = _POS;
    vel     = new PVector( random(-1,1), random(-1,1), 0 );
    maxVel  = random(2.0,6.0);        // random number between 2 & 6 units
    sSize   = _S;
    spotCol = 200;
  }
 
  // *** CLASS METHODS & BEHAVIOURS ***  
 
  // Primary Method - call all other functions here
  void update(){
    pos.add(vel);  // simply add the veocity to the current position of the spot!
    render();  // call our fucntion that draws the spot!
  } 
 
  // Method to draw the spot
  void render(){
    stroke(spotCol);
    fill(spotCol,60);
    ellipseMode(CENTER);
    ellipse(pos.x,pos.y, sSize, sSize);
  }   
}
 
/*-------------------------------------------------------------------------------------------------
 Declare our variables
 -------------------------------------------------------------------------------------------------*/
 
int numSpots  = 100;                          // How many RED spots to make???
float minSize = 10;                           // Minimum size of our spots
float maxSize = 35;                           // Maximum size of our spots
 
SuperSpot [] spots;                           // Declare our array
 
 
/*-------------------------------------------------------------------------------------------------
 Setup Sketch
 -------------------------------------------------------------------------------------------------*/
void setup(){
  size(650,300);                               // set the applet size to 500x500 pixels
  background(0);                               // set the applet background to black
  frameRate(20);
 
  spots = new SuperSpot[numSpots];             // make our array of RED spots
 
  // loop to make our spot objects
  for(int i = 0; i < numSpots; i++){
    spots[i] = new SuperSpot( new PVector(random(0,width), random(0,height),0), random(minSize,maxSize));                   
  }
 
}
 
/*-------------------------------------------------------------------------------------------------
 Draw Loop
 -------------------------------------------------------------------------------------------------*/
void draw(){
  background(0);                               // Set the applet background to black
 
  // A simple loop to update each RED spot object
  for(int i = 0; i < spots.length; i++){
    spots[i].update();                         // Call the update method for each spot -- See SuperSpot class for what SuperSpot.update() does!!!   
  }
 
}

Introduction: Physical Forces
Physical forces are any external forces that may influence the motion (speed & direction) of an object. These are also commonly referred to as lateral forces. Such forces may include gravity, drag, etc, or be of a more advanced nature such as the steering behaviours of autonomous agents. The easiest way to handle these forces is to calculate and store them as an additional vector called accelleration. The acceleration is then passed onto the velocity of the object to finally establish the object’s new position. Tis may seem a bit of a long way round, but there are advantages to storing the summed result of the effects in our acceleration vector, primarally as we may wish to weight the influence of each of these forces, or indeed the weight the general influence of acceleration forces on the desire (speed and heading) of the object itself.

Example 02: Applying Gravity to an object
Here we extend our previous example by adding a third vector for acceleration. The acceleration vector will be used store gravity, but could be easilly extended to consider otehr factors such as drag, attraction, repulsion, or the rebound force of bumping into another object if we so desired. As these forces can vary according to distance and otehr variables, we generally calculate the sum of all these effects each iteration and pass it to the velocity. As these also can get out of hand (too big in influence), we generally also need to introduce a speed control mechanism – a maximum velocity parameter – to ensure the object’s motions stays within a desired range.

 
/*-------------------------------------------------------------------------------------------------
 Object Class
 -------------------------------------------------------------------------------------------------*/
// Our class receives a position, size and 3 values pertaining to its draw colour
class SuperSpot
{
  // *** CLASS VARIABLES ***
  PVector pos, vel, acc;
  float maxVel, drag;
  float sSize;
  int spotCol;
 
  // *** CLASS CONSTRUCTOR ***
  SuperSpot(PVector _POS, float _S){
    pos     = _POS;
    vel     = new PVector( random(-1,1), random(-1,1), 0 );
    acc     = new PVector(0, 9.8, 0); // gravity would be 9.8 metres per second in the y directions
    maxVel  = random(2.0,6.0);        // random number between 2 & 6 units
    drag      = 0.5;                  // just some number
    sSize   = _S;
    spotCol = 200;
  }
 
  // *** CLASS METHODS & BEHAVIOURS ***  
 
  // Primary Method - call all other functions here
  void update(){
    updateMotion(); // call our custom update motion
    render(); // our custom function that draws the dot
  } 
 
  // apply physics
  void updateMotion(){
    acc.mult(drag);     // multiply the acceleration by the constant of drag!
    vel.add(acc);
    vel.limit(maxVel);  // limit the speed of the object to a known maximum
    pos.add(vel);
  }
 
  // Method to draw the spot
  void render(){
    stroke(spotCol);
    fill(spotCol,60);
    ellipseMode(CENTER);
    ellipse(pos.x,pos.y, sSize, sSize);
  }   
}
 
/*-------------------------------------------------------------------------------------------------
 Declare our variables
 -------------------------------------------------------------------------------------------------*/
 
int numSpots  = 100;                          // How many RED spots to make???
float minSize = 10;                           // Minimum size of our spots
float maxSize = 35;                           // Maximum size of our spots
 
SuperSpot [] spots;                           // Declare our array
 
 
/*-------------------------------------------------------------------------------------------------
 Setup Sketch
 -------------------------------------------------------------------------------------------------*/
void setup(){
  size(650,300);                               // set the applet size to 500x500 pixels
  background(0);                               // set the applet background to black
  frameRate(20);
 
  spots = new SuperSpot[numSpots];             // make our array of RED spots
 
  // loop to make our spot objects
  for(int i = 0; i < numSpots; i++){
    spots[i] = new SuperSpot( new PVector(random(0,width), random(0,height),0), random(minSize,maxSize));                   
  }
 
}
 
/*-------------------------------------------------------------------------------------------------
 Draw Loop
 -------------------------------------------------------------------------------------------------*/
void draw(){
  background(0);                               // Set the applet background to black
 
  // A simple loop to update each RED spot object
  for(int i = 0; i < spots.length; i++){
    spots[i].update();                         // Call the update method for each spot -- See SuperSpot class for what SuperSpot.update() does!!!   
  }
 
}

About this entry