Vectors Everywhere

(Versão em Português)
A vaporwave-style GIF with a camera moving through a checkered road under rain, palm trees on the sides, mountains in the background, and a large moon in the sky.

I thought I would never use Cartesian planes again in my life.

Don't get me wrong, but when I was still in school, some subjects were difficult for me, like organic chemistry, Cartesian planes and cloud names.

But here I am, normalizing vectors, discovering their magnitudes, and doing basic arithmetic with them. All of this is thanks to the amazing book The Nature of Code by Daniel Shiffman. This post is my attempt to share what I’ve learned.

You can check out the previous chapter's post.

Vectors

My sad attempt to create a bee (yellow circle) being chased by a bird (blue triangle) in a green field (Source Code)

The term "vector" can have various definitions, but let's focus on the Euclidean vector, an entity with size and direction. Mathematically, this size is called magnitude.

Vectors appear in many contexts, such as 2D, 3D, machine learning, and data analysis. But here, we will stick to 2D (two dimensions).

Typically, we can represent a vector using an arrow:

An image containing an arrow representing a vector. The arrow is black, and the background is white.

But, how can we position these points in a two-dimensional space?

By using a Cartesian plane. The representation looks like this: (3,5), where 3 is the coordinate on the X-axis and 5 on the Y-axis.

An image containing a vector (3,5) on a Cartesian plane

The vector provides the instructions to move from the origin (0,0) to the desired point, in this case, (3,5).

But, how can we represent vectors in p5.js?

The difference is that the origin (0,0) in p5.js is represented in the top-left corner:

An image containing a vector (3,5) in p5.js

The idea in p5.js is that with each frame of the animation (draw), we can move our object a certain vertical and horizontal distance. This is a vector, with magnitude (size of the distance) and direction. In other words, a vector defines the velocity of the object.

If you didn't understand anything I said, I recommend you read the previous chapter's post or consult Daniel Shiffman's book, The Nature of Code (NOC), directly.

But, how can we modify the speed of an object using a vector?

Through vector operations.

Vector Operations

We can perform the main arithmetic operations with vectors: addition, subtraction, division, and multiplication. The NOC already explains these operations in detail, so I'll just summarize.

The addition of two vectors results in a new vector with the sum of their magnitudes. Subtraction returns the difference between two vectors.

Ball moving using vectors (Source Code)

First, we create two vectors, one for position and another for velocity:

function setup() {
  position = createVector(100, 100);
  velocity = createVector(3, 3);

  createCanvas(widthFormat, heightFormat);
  background(255);
}

Then, we add the velocity to the position and draw the ellipse on the screen:

function draw() {
  position.add(velocity);
  circle(position.x, position.y, ballSize);
}

These two steps together form the basic concept of motion, called Motion 101.

However, this movement doesn't do much; let's add some acceleration.

Acceleration

Acceleration is the rate of change of velocity. It’s a vector that changes the velocity, which in turn changes the position, like a cascade effect:

velocity.add(acceleration);
position.add(velocity);

Finally, the code below creates an ellipse that accelerates toward the mouse:

Ball accelerating toward the mouse (Source Code)

We've reached the end of vectors, and I often find myself thinking about how a bunch of simple code can create such amazing things.

Now that I understand a little about randomness and motion, things are starting to get interesting.