How to Find Collision Impulse in Matter.js

This article explains how to determine the impulse applied to bodies during a collision in the Matter.js 2D physics engine. Matter.js calculates linear and angular impulses internally to resolve penetrations and bounce bodies apart. By intercepting collision events and inspecting the internal properties of collision pairs—or by measuring the resulting change in momentum—you can accurately measure the force of impact for damage calculations, sound triggering, or custom game logic.

Method 1: Reading Impulses from Collision Contacts

Matter.js tracks contact points between colliding pairs and calculates the normal and tangential impulses during the collision resolution step. Each collision pair contains a list of contact points, each holding its resolved impulse values.

Because impulses are applied during the collision solve step, they are fully populated in the collisionActive event or in an afterUpdate listener immediately following collisionStart.

Matter.Events.on(engine, 'collisionActive', (event) => {
    event.pairs.forEach((pair) => {
        let totalNormalImpulse = 0;
        let totalTangentImpulse = 0;

        pair.contacts.forEach((contact) => {
            // normalImpulse represents the direct impact force
            totalNormalImpulse += contact.normalImpulse || 0;
            // tangentImpulse represents the frictional impulse along the surface
            totalTangentImpulse += contact.tangentImpulse || 0;
        });

        // Combined magnitude of the impulse applied this frame
        const totalImpulse = Math.hypot(totalNormalImpulse, totalTangentImpulse);

        if (totalImpulse > 0) {
            console.log(`Impulse between ${pair.bodyA.label} and ${pair.bodyB.label}:`, totalImpulse);
        }
    });
});

Method 2: Calculating Impulse via Change in Momentum

If you require the impulse magnitude directly at collisionStart before the internal contact impulses are updated, or if you want a physics-agnostic value, you can calculate the impulse using the impulse-momentum theorem:

\[\vec{J} = m \Delta \vec{v} = m (\vec{v}_{\text{after}} - \vec{v}_{\text{before}})\]

To do this:

  1. Record each body's velocity in the beforeUpdate event.
  2. In the afterUpdate event, compare the recorded velocity to the new velocity for any bodies that collided.
const preVelocities = new Map();

// 1. Store velocities before collisions are solved
Matter.Events.on(engine, 'beforeUpdate', () => {
    engine.world.bodies.forEach((body) => {
        preVelocities.set(body.id, { x: body.velocity.x, y: body.velocity.y });
    });
});

// 2. Measure the delta after collisions are resolved
Matter.Events.on(engine, 'afterUpdate', () => {
    // Alternatively iterate through engine.pairs.list
    engine.world.bodies.forEach((body) => {
        if (body.isStatic) return;

        const pre = preVelocities.get(body.id);
        if (!pre) return;

        const deltaVx = body.velocity.x - pre.x;
        const deltaVy = body.velocity.y - pre.y;
        const deltaV = Math.hypot(deltaVx, deltaVy);

        // Impulse magnitude: J = mass * deltaV
        const impulse = body.mass * deltaV;

        if (impulse > 0.1) {
            // Body experienced an external impulse
            console.log(`Body ${body.id} experienced an impulse of:`, impulse);
        }
    });
});

Key Differences Between Methods