Introduction to Vectors for Autonomous Agents in P5.js
Table of contents
TL;DR ๐
This article introduces the fundamental concepts of vectors and their applications in creating autonomous agents using P5.js. It covers the definition and properties of vectors, basic vector operations (addition, subtraction, scalar multiplication, magnitude, normalization, and dot product), and provides examples of simple simulations like bouncing and accelerating towards the center. The article aims to equip beginners with the essential skills to manipulate vectors for realistic and dynamic movement behaviors in simulations and games. Future posts will explore advanced topics like steering behaviors.
Introduction
What is an autonomous agent
An autonomous agent is an entity that can make decisions and act independently within an environment. These agents are capable of perceiving their surroundings, processing information, and taking actions to achieve specific goals. In simulations and games, autonomous agents are used to create realistic behaviors for characters, such as navigating through a space, avoiding obstacles, and interacting with other agents. And I love it. ๐
Importance of vectors in animation and simulation
Vectors play a crucial role in animation and simulation by providing a mathematical way to represent direction and magnitude. They are used to calculate movement, forces, and interactions between objects. In the context of autonomous agents, vectors are essential for defining behaviors such as seeking, fleeing, and wandering. By manipulating vectors, developers can create complex and realistic movement patterns that enhance the believability of the agents.
Objective of the article
The objective of this article is to provide a beginner-friendly introduction to the fundamental concepts of vectors and their applications in creating autonomous agents using P5.js. By understanding the basic properties and operations of vectors, you will gain the foundational knowledge needed to implement realistic and dynamic movement behaviors in simulations and games. This article aims to equip newcomers with the essential skills to manipulate vectors, setting the stage for more advanced topics such as steering and evasion behaviors in future posts. Stay tuned for upcoming posts ๐
Basics of Vectors
Definition and properties of vectors
A vector is a mathematical entity that has both magnitude and direction. Vectors are often represented as arrows in a coordinate system, where the length of the arrow indicates the magnitude and the direction of the arrow indicates the direction. Vectors are fundamental in physics and engineering, as they can represent quantities such as velocity, force, and displacement.
Basic vector operations
Addition
Vector addition involves combining two vectors to produce a third vector. This is done by adding the corresponding components of the vectors. For example, if vector A has components (Ax, Ay)
and vector B has components (Bx, By)
, the resultant vector C = A + B
will have components (Ax + Bx, Ay + By)
.
use case : In video game development, vector addition is used to combine the movements of multiple characters or objects. For example, if a character is moving forward and also being pushed to the side by wind, the final movement direction and speed can be calculated by adding the forward movement vector and the wind vector. This ensures realistic and dynamic interactions between different forces acting on the character.
vectorA = createVector(100, 130);
vectorB = createVector(200, 40);
vectorC = p5.Vector.add(vectorA, vectorB);
// https://p5js.org/reference/p5.Vector/add/
Find the code here : Addition ๐
Subtraction
Vector subtraction is similar to addition but involves subtracting the corresponding components of the vectors. If vector A has components (Ax, Ay)
and vector B has components (Bx, By)
, the resultant vector C = A - B
will have components (Ax - Bx, Ay - By)
.
use case : In video game development, vector subtraction is used to determine the relative position between two objects. For example, if you have a player character and an enemy, you can subtract the enemy's position vector from the player's position vector to get a vector that points from the enemy to the player. This can be used to calculate the direction in which the enemy should move to chase the player or to determine the distance between them for collision detection.
vectorA = createVector(350, 150);
vectorB = createVector(300, 40);
vectorC = p5.Vector.sub(vectorA, vectorB);
// https://p5js.org/reference/p5.Vector/sub/
Find the code here : Subtraction ๐
Scalar multiplication
Scalar multiplication involves multiplying a vector by a scalar (a single number). This operation scales the vector by the given scalar. If vector A has components (Ax, Ay)
and is multiplied by a scalar k, the resultant vector B = kA
will have components (kAx, kAy)
.
use case : In video game development, scalar multiplication is used to adjust the speed of a character or object. For example, if a character is moving in a certain direction and you want to increase or decrease their speed, you can multiply their velocity vector by a scalar value. This allows for smooth acceleration and deceleration, making the movement more realistic. Scalar multiplication is also used in animations to scale transformations, such as resizing objects or changing their intensity over time.
vectorA = createVector(200, 100);
scalar = 1.4;
vectorB = p5.Vector.mult(vectorA, scalar);
// https://p5js.org/reference/p5.Vector/mult/
Find the code here : Multiplication ๐
Magnitude
The magnitude of a vector is a measure of its length. For a vector A with components (Ax, Ay)
, the magnitude |A|
is calculated using the Pythagorean theorem: |A| = โ(Axยฒ + Ayยฒ)
.
use case : In navigation systems and robotics, the magnitude of vectors is used to calculate the distance traveled or the distance to a target, which is crucial for path planning and movement control
vectorA = createVector(200, 100)
magnitudeA = vectorA.mag();
// https://p5js.org/reference/p5.Vector/mag/
Find the code here : Magnitude ๐
Normalization
Normalization is the process of converting a vector to a unit vector (a vector with a magnitude of 1) while maintaining its direction. For a vector A with components (Ax, Ay)
, the normalized vector A'
is obtained by dividing each component by the magnitude of the vector: A' = (Ax / |A|, Ay / |A|)
.
use case : This is useful when you need to preserve the direction but not the magnitude, such as when defining a direction for movement or orientation. In autonomous systems, normalized vectors are used to define direction vectors for steering behaviors like seeking, fleeing, and wandering. Normalization ensures that the direction is consistent and the magnitude can be scaled as needed.
vectorA = createVector(200, 100);
normalizedA = vectorA.normalize();
// https://p5js.org/reference/p5.Vector/normalize/
Dot product
The dot product, also known as the scalar product, is an operation that takes two vectors and returns a single scalar value. For vectors A with components (Ax, Ay)
and B(Bx, By)
, the dot product A ยท B
is calculated as: A ยท B = Ax Bx + Ay By
use case: In video game development, the dot product is used to determine if two vectors are aligned, which is essential for various gameplay mechanics. For example, if you want to check if a character is facing an enemy, you can use the dot product of the character's forward direction vector and the vector pointing towards the enemy. If the dot product is close to 1, the vectors are aligned, indicating the character is facing the enemy. If the dot product is close to -1, the vectors are opposite, and if it is close to 0, the vectors are perpendicular. This technique helps in implementing features like targeting systems, field of view checks, and directional attacks.
vectorA = createVector(200, 100);
vectorB = createVector(100, 50); // Same exact direction (scaled)
normalizedA = vectorA.copy().normalize();
normalizedB = vectorB.copy().normalize();
console.log(`Dot product of A and B: ${normalizedA.dot(normalizedB)}`);
// https://p5js.org/reference/p5.Vector/dot/
Find the code here : Dot Product ๐
Basic simulation
Simple bounce
let agent;
let velocity;
let acceleration;
function setup() {
createCanvas(800, 200);
agent = createVector(width / 2, height / 2);
velocity = createVector(2, 2);
acceleration = createVector();
}
function draw() {
background(2, 6, 23);
acceleration = velocity.copy().normalize().mult(0.01);
velocity.add(acceleration);
agent.add(velocity);
if (agent.x > width || agent.x < 0) {
velocity.x *= -1;
}
if (agent.y > height || agent.y < 0) {
velocity.y *= -1;
}
fill(255, 100, 100);
ellipse(agent.x, agent.y, 20, 20);
}
Find the code here : Bouncy Agent ๐
The provided code is a simple simulation of an agent using the principles of velocity and acceleration in P5.js. This one will constantly accelerate and bounce on the boundary of the canvas. Here is the breakdown of the code :
Initialization:
agent
: This is a vector representing the position of the agent, initialized at the center of the canvas.velocity
: This vector represents the agent's velocity, initialized with a value of (2, 2).acceleration
: This vector represents the agent's acceleration, initialized with a value of (0, 0).
Setup Function:
The agent's position is set to the center of the canvas.
The velocity is set to (2, 2), meaning the agent will initially move diagonally.
Draw Function:
acceleration = velocity.copy().normalize().mult(0.01)
: The acceleration is calculated by normalizing the velocity vector (making it a unit vector) and then scaling it by 0.01. This ensures the acceleration is in the direction of the velocity but with a very small magnitude.velocity.add(acceleration)
: The acceleration is added to the velocity, causing the agent to gradually speed up in the direction it is moving.agent.add(velocity)
: The velocity is added to the agent's position, updating its location on the canvas.Boundary checks: If the agent moves outside the canvas boundaries, the velocity in the respective direction is reversed, causing the agent to bounce back.
Principles:
Velocity: Represents the speed and direction of the agent's movement. It is continuously updated by adding the acceleration.
Acceleration: Represents the change in velocity. In this code, it is a small value in the direction of the current velocity, causing the agent to gradually speed up.
Normalization: Ensures the acceleration vector has a consistent direction but a controlled magnitude.
Simple accleration toward center
let agent;
let velocity;
let acceleration;
let topspeed = 5;
function setup() {
createCanvas(800, 200);
agent = createVector(0, 0);
velocity = createVector(0, 10);
acceleration = createVector();
}
function draw() {
background(2, 6, 23);
let centerPos = createVector(width / 2, height / 2);
let direction = p5.Vector.sub(centerPos, agent);
acceleration = direction.setMag(0.2);
velocity.add(acceleration);
velocity.limit(topspeed);
agent.add(velocity);
fill(255, 100, 100);
ellipse(agent.x, agent.y, 20, 20);
}
Find the code here : Accelerating Agent ๐
This agent will constantly accelerate towards the center of the canvas. Here is the breakdown of the code :
Initialization:
agent
: This is a vector representing the position of the agent.velocity
: This vector represents the agent's velocity.acceleration
: This vector represents the agent's acceleration.topspeed
: This is a scalar value representing the maximum speed the agent can reach, set to 5.
Setup Function:
The agent's position is set to the top-left corner of the canvas.
The velocity is set to (0, 10), meaning the agent will initially move downward.
Draw Function:
centerPos
is a vector representing the center of the canvas.direction
is calculated as the vector pointing from the agent's current position to the center of the canvas.acceleration = direction.setMag(0.2)
: The acceleration is calculated by setting the magnitude of the direction vector to 0.2. This ensures the acceleration is directed towards the center of the canvas.
acceleration = direction.setMag(0.2);
// is the same as
acceleration = direction.normalize().mult(0.2);
velocity.add(acceleration)
: The acceleration is added to the velocity, causing the agent to gradually speed up towards the center.velocity.limit(topspeed)
: The velocity is limited to the maximum speed defined bytopspeed
, ensuring the agent does not move too fast.agent.add(velocity)
: The velocity is added to the agent's position, updating its location on the canvas.
Conclusion
Recap of key concepts
In this article, we explored the fundamental concepts of vectors using P5.js. Here are the key takeaways:
Importance of Vectors: Vectors are crucial in animation and simulation for representing direction and magnitude. They help in calculating movement, forces, and interactions between objects, enabling realistic and dynamic behaviors.
Vector Basics:
Definition: A vector has both magnitude and direction, often represented as arrows in a coordinate system.
Addition: Combining two vectors to produce a third vector by adding their corresponding components.
Subtraction: Determining the relative position between two vectors by subtracting their corresponding components.
Scalar Multiplication: Scaling a vector by multiplying it with a scalar value.
Magnitude: The length of a vector, calculated using the Pythagorean theorem.
Normalization: Converting a vector to a unit vector while maintaining its direction.
Dot Product: An operation that returns a scalar value, used to determine if two vectors are aligned.
Basic Simulation:
Simple Bounce: Demonstrates an agent that constantly accelerates and bounces on the boundary of the canvas using principles of velocity and acceleration.
Simple Acceleration Toward Center: Illustrates an agent that constantly accelerates towards the center of the canvas, showcasing the use of direction vectors and controlled acceleration.
In the next post, we will dive into the fascinating world of steering behaviors! Get ready to explore how autonomous agents can exhibit intelligent and lifelike movements by seeking, fleeing, and wandering. We'll uncover the secrets behind creating agents that can navigate complex environments, avoid obstacles, and interact dynamically with other agents. Stay tuned for an exciting journey into the advanced techniques that will bring your simulations and games to life! ๐
References
"The Nature of Code" book and online tutorials by Daniel Shiffman
P5.js reference and examples: P5.js Reference
P5.js community: P5.js Forum
Thank you for reading my blog ! If you enjoyed this post and want to stay connected, feel free to connect with me on LinkedIn. I love networking with fellow developers, exchanging ideas, and discussing exciting projects.
Connect with me on LinkedIn ๐
Looking forward to connecting with you ! ๐
Subscribe to my newsletter
Read articles from Arnauld Alex directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Arnauld Alex
Arnauld Alex
I am a dedicated AI game programmer, former software engineer in aeronautics domain. With a strong passion for AI, game programming, and full-stack development. I thrive on learning new technologies and continuously improving my skills. As a supportive and collaborative person, I believe in adding value to every project and team I work with. Connect with me on LinkedIn