Vectors 101, in Processing

What is a Vector?


In short, we use Vectors when we want to move something. When describing the placement of an object in space, we're familiar to specifying the position with variables, such as x, y, and z. These location variables become inherent to any object that we want to move. In code, the word Vector has a few meanings, but in this case it simply means a collection of values that describe a position in space. In Processing, a Vector is simply an object that already contains x, y, and z variables for moving things around. Simple, but very powerful! In using Vectors you are opening the door to the entire realm of Vector Math. But, for now, it's let's just think of a Vector as a collection of spacial values for you to use when it's appropriate. Processing has a Vector object built in, called the PVector. There is an excellent tutorial on Vectors by Daniel Shiffman on Processing.org




Why are Vectors useful?


They're useful because they allow you to store position variables in ONE variable, rather than 2 (or 3). It can code easier to think about, and you're able to use built-in functions that come with Processing.

For example:

Let's say we're creating a thing that's moving through space. That object may contain the variables:

float x, y, xspeed, yspeed;

It would be much more convenient to just have position and speed as their own variables. With vectors, we can do that.

PVector position, speed;

In order to access the x, and y values from the PVector, we can get to them by using the DOT syntax:

position.x = 50;
position.y = 20;
speed.x = -1;
speed.y = 0.5;

Example of code written with x and y values. This example is a Ball that follows the Mouse.



// position
float x,y;
// velocity
float vx,vy;

void setup() {
size(512,512);
x = 10;
y = 10;
}

void draw() {

background(40);

// add velocity to the vector by subtracting the current position
// from the mouse position
if (mousePressed) {
vx = mouseX - x;
vy = mouseY - y;
vx *= 0.2;
vy *= 0.2;
}

// adding the velocity vector to the position vector
x += vx;
y += vy;

// multiplying the velocity to "dampen" it
vx *= 0.8;
vy *= 0.8;

// draw
fill(255);
ellipse(x,y,40,40);
}

The same code written with a Vector to handle the velocity and the position variables:



// position
PVector pos;
// velocity
PVector vel;

void setup() {
size(512,512);
pos = new PVector(width/2, height/2);
vel = new PVector();
}

void draw() {

background(40);

// add velocity to the vector by subtracting the current position
// from the mouse position
if (mousePressed) {
vel.add(new PVector((mouseX-pos.x), (mouseY-pos.y)));
vel.mult(0.1);
}

// adding two vectors
pos.add(vel);
vel.mult(0.9);

fill(255);
ellipse(pos.x, pos.y, 40, 40);
}

Notice we're using Object Oriented Programming techniques when we're using the PVector object. Because, quite simply, it's a Class just the same as you would defined yourselves. You could potentially craft your own Vector class if you wanted. So, in using PVector we need to use the 'new' keyword every time we create a new instance, just as if it was a normal object of any other class.

Inside the class folder under '_examples' are examples of how to use Vector class.

You can also find them here: Vectors

Calculating Circle Intersections with Vectors



Circle c1, c2;

void setup()
{
size(600, 300);
strokeWeight(2);
smooth();

c1 = new Circle( 400, 150 );
c2 = new Circle( 400, 150 );
}


void draw()
{
background(150);

c2.pos = new PVector( mouseX, mouseY );

// fluctuate radius with sin()
c1.radius = ((sin(frameCount / 30.0) + 1) / 2 * 75) + 25;

// calculate intersection by comparing distances between Circles
if (c2.pos.dist(c1.pos) < c2.radius + c1.radius) {
stroke(200,0,0);
} else {
stroke(0);
}

// point at opposing circle
c1.pointAt(c2.pos);
c2.pointAt(c1.pos);

// draw
c1.draw();
c2.draw();
}


class Circle
{
PVector pos;
float radius = 100;
float theta = 0;

Circle( float _x, float _y ) {
pos = new PVector(_x, _y);
}

void draw()
{
noFill();

// ellipse
ellipse( pos.x, pos.y, radius * 2, radius * 2 );
point( pos.x, pos.y );

// angle
pushMatrix();
translate(pos.x, pos.y);
rotate( theta );
line(0, 0, radius, 0);
popMatrix();
}

void pointAt(PVector p)
{
theta = atan2(p.y - pos.y, p.x - pos.x);
}
}
More examples of the smoothness of movement by using a velocity vector to ease-in the object.Source code for all examples in this post: Vectors.tar.gz