How to Normalize Vectors in Matter.js
This article explains how to compute a unit vector from an arbitrary
displacement vector in Matter.js using the built-in
Matter.Vector.normalise method. You will learn the
mathematical concept behind vector normalization, the exact syntax
required by the Matter.js physics engine, and how to apply the resulting
unit vector to control movement and directional forces in your
simulations.
Understanding Displacement and Unit Vectors
A displacement vector represents the distance and direction between two points in 2D space. A unit vector—also known as a normalized vector—retains the exact same direction as the original displacement vector, but its magnitude (length) is scaled down to 1. Unit vectors are essential in physics engines for applying uniform forces, setting projectile velocities, and calculating collision trajectories without the magnitude of the distance skewing the physics calculations.
Step-by-Step Implementation
To calculate a unit vector from two positions, you first calculate
the displacement vector and then pass it to
Matter.Vector.normalise.
1. Calculate the Displacement Vector
Subtract the origin point (point A) from the target point (point B)
using Matter.Vector.sub:
const pointA = { x: 50, y: 100 };
const pointB = { x: 200, y: 300 };
// Displacement = Point B - Point A
const displacement = Matter.Vector.sub(pointB, pointA);
// displacement is { x: 150, y: 200 }2. Normalize the Vector
Pass the displacement vector to Matter.Vector.normalise.
The function divides both components (\(x\) and \(y\)) by the vector's total length (computed
via the Pythagorean theorem: \(\sqrt{x^2 +
y^2}\)).
const unitVector = Matter.Vector.normalise(displacement);
// unitVector is approximately { x: 0.6, y: 0.8 }The resulting unitVector has a magnitude of precisely 1,
pointing from pointA toward pointB.
Complete Code Example
// Import or alias the Matter.js Vector module
const Vector = Matter.Vector;
// Define two positions in your 2D world
const startPosition = { x: 10, y: 20 };
const targetPosition = { x: 70, y: 100 };
// 1. Calculate the displacement between the two positions
const displacement = Vector.sub(targetPosition, startPosition);
// 2. Compute the unit vector
const unitVector = Vector.normalise(displacement);
// 3. (Optional) Apply a specific speed or force along this direction
const speed = 5;
const velocity = Vector.mult(unitVector, speed);
console.log("Unit Vector:", unitVector);
console.log("Magnitude:", Vector.magnitude(unitVector)); // Outputs: 1
console.log("Scaled Velocity:", velocity);Handling Zero-Length Vectors
If the start position and target position share the exact same
coordinates, the displacement vector is { x: 0, y: 0 }. In
this scenario, the magnitude is zero. Dividing by zero returns
NaN in standard mathematics. In Matter.js,
Matter.Vector.normalise safely handles this by returning
{ x: 0, y: 0 } if the magnitude is zero, preventing
numerical instability in your physics world.