Find Collision Normal Vector in Matter.js

This article explains how to retrieve and utilize the collision normal vector in Matter.js. You will learn which event listener to hook into, where the normal vector is stored within the collision data structures, how to interpret its directional orientation between two colliding bodies, and how to apply this data in your physics simulations.

Listening to Collision Events

To access collision data in Matter.js, attach a listener to the Engine instance using Matter.Events. The most common events for detecting impacts are collisionStart and collisionActive.

Matter.Events.on(engine, 'collisionStart', (event) => {
    const pairs = event.pairs;

    for (let i = 0; i < pairs.length; i++) {
        const pair = pairs[i];
        // Access collision data here
    }
});

Accessing the Normal Vector

Each collision pair contains a collision object that holds geometric details about the impact. The normal vector is stored directly in pair.collision.normal.

const normal = pair.collision.normal;
console.log(`Normal X: ${normal.x}, Normal Y: ${normal.y}`);

The normal property is a normalized 2D vector object with x and y coordinates representing a unit vector (magnitude of 1) perpendicular to the contacting surface.

Interpreting Vector Direction

Matter.js defines the collision normal relative to the two bodies involved: pair.bodyA and pair.bodyB.

Complete Implementation Example

const { Engine, Render, Runner, Bodies, Composite, Events, Vector } = Matter;

const engine = Engine.create();
// Setup bodies and world...

Events.on(engine, 'collisionStart', (event) => {
    event.pairs.forEach((pair) => {
        const { bodyA, bodyB, collision } = pair;
        const normal = collision.normal;

        // Normal pointing from bodyA to bodyB
        const normalAtoB = { x: normal.x, y: normal.y };

        // Inverted normal for bodyA
        const normalBtoA = Vector.negate(normalAtoB);

        console.log(`Collision between ${bodyA.label} and ${bodyB.label}`);
        console.log('Surface Normal (A -> B):', normalAtoB);
        console.log('Surface Normal (B -> A):', normalBtoA);
    });
});

Key Considerations