Vectors and Forces: Part 1

In programming, vectors are integral to any code that is simulating real world forces. They allow us to easily simulate complicated ranges of motion as we can easily create new vectors for different forces.

vectors

Image by the Daniel Shiffman: The Nature of Code

The above diagram is an example of 2D vectors. A simple way to think of them is the difference between two points in space. In class, we devised a vector class, here it is below:

//Vectors
Vect v1, v2;
float f = 9;

void setup(){
  size(500,500);
  v1 = new Vect(20, 50);
  v2 = new Vect(100, 30);
  
  v1.add(v2);
  
  println(f);
}

void draw(){
  
  println(v2.x);
  
  
}


class Vect{
 
 float x, y;
 
  Vect(float x, float y){
    this.x = x;
    this.y = y;
    } 
//Method overloading: Multiple variations of method
//Can add different values
  Vect(){
    x = 0;
    y = 0;
    }
    
    //add an adding method
    void add(Vect v){
      x = x + v.x;
      y = y + v.y;
    }
    

// In Java object will inherit default values

Although this code returns a blank sketch, this is the base for a simple 2D vector with adding capabilities. The vector is first initialized and the variables declared. The main piece of information we need the class store is both x and y co-ordinates, which we declare as floating point values to get the greatest precision from them. As in Java classes by default inherit blank values we need to initialize them. We can then add a method so that the vectors can be added together. In order to create a fully comprehensive vector class we would have to add a lot more methods like these, such as multiplication and subtraction for it to be fully useful.

Thankfully Processing has built in vector libraries which we can use instead of having to create vector classes each time. In class we created a physics simulation with many different forces to learn about this. In this sketch there is a bouncing ball that reacts to gravity and drag. It is also “pushed” by a force with a vector coming from the mouse.

PVector position, velocity, centre;

void setup(){
 size(600, 600); 
 position = new PVector(50, 50);
 velocity = new PVector(6, 3);
 centre = new PVector(0.5*width, 0.5*height);
 strokeWeight(4);
}

void draw(){
  background(255);
  velocity.add( mouseForceTo(centre) ); //add force from mouse
  line(centre.x, centre.y, mouseX, mouseY);
  //simulating gravity
  velocity.add(0, 0.2, 0);
  
  //simulating wind
  //velocity.add(0.05, 0, 0);
  
  //simulating drag
  velocity.mult(0.98);
  
  //add velocity to position every frame
  position.add(velocity);
  bounce();
    point(position.x, position.y);
}
 
 
 void bounce(){
   if (position.x > width || position.x < 0){
     velocity.x = -velocity.x;
   }
   
   //more accurate method
   if(position.y > height){
     //make sure even at high velocities
     //it does not go past canvas and get trapped
     position.y = height;
     velocity.y = -velocity.y;
   }else if(position.y < 0){
     position.y = 0;
     velocity.y = -velocity.y;
   }
   
     
 }
 
 //Vector to add wind from mouse
 PVector mouseForceTo(PVector origin){
  PVector tmp = origin.get();
  tmp.sub(mouseX, mouseY, 0);
  tmp.mult(0.005);
   return tmp; 
 }
  

In the above sketch, PVector is used for the position, velocity and the center positions.
Velocity is one of the most important vectors here as this is the one that gets modified whenever we want to add a new force to the object. For example we add the vector (0, 0.2 , 0) to the velocity each frame in order to simulate gravity on the object. (Y values go up the further down the screen you go, so gradually adding to this each frame is a simple way to simulate gravity.) Drag is simulated by multiplying the velocity by 0.98 each time, meaning the total velocity is always slightly decreasing. After calculating the total velocity with all the forces acting upon it, it gets added to the position.

The ball is kept in frame by making the velocity negative in that axis when meeting the frame on that axis. There is a more accurate way to do this though, by first snapping the ball to the edge of the frame before reversing the velocity the ball will not go past the frame, which can be a problem at higher velocities as it will not always be exactly connecting with the frame on the tick when the calculation is done. However this can also lead to some unnatural angles at which the ball bounces, which might be a problem at higher level simulations.

Shiffman, D., 2012. The Nature of Code [online] Mountain View: Creative Commons

Leave a Comment