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.