How to Create a Rotary Damper in Matter.js

This article explains how to construct a rotary damper joint in Matter.js to resist rapid angular rotation. While Matter.js includes standard linear spring-damper constraints, it lacks a native rotational viscous damper. You can achieve this effect by pairing a standard pin constraint with an event hook that dynamically applies a counteracting torque proportional to the relative angular velocity between two bodies.

Understanding the Physics

A rotary damper (or torsional dashpot) exerts a torque that opposes the direction of angular movement. The magnitude of this torque is directly proportional to the angular velocity:

\[\tau = -c \cdot \Delta\omega\]

Where:

Step 1: Create the Pin Constraint

First, establish a standard revolute joint using a Constraint that binds Body A to Body B at a shared pivot point without restricting rotation:

const { Bodies, Constraint, Composite } = Matter;

const bodyA = Bodies.rectangle(400, 300, 200, 20, { isStatic: true });
const bodyB = Bodies.rectangle(400, 300, 150, 20);

// Pin constraint serving as the axle
const pinJoint = Constraint.create({
    bodyA: bodyA,
    pointA: { x: 0, y: 0 },
    bodyB: bodyB,
    pointB: { x: -60, y: 0 },
    length: 0,
    stiffness: 1
});

Composite.add(world, [bodyA, bodyB, pinJoint]);

Step 2: Implement Dynamic Angular Damping

To resist rapid turns, hook into the beforeUpdate event of the physics engine. In this callback, calculate the relative angular velocity between the bodies and apply an opposing torque directly to the rotating body's torque property before each physics step.

const { Events } = Matter;

// Higher values resist faster rotations more aggressively
const rotaryDamping = 0.05; 

Events.on(engine, 'beforeUpdate', () => {
    // Determine relative angular speed
    const angularVelocityA = bodyA.isStatic ? 0 : bodyA.angularVelocity;
    const angularVelocityB = bodyB.isStatic ? 0 : bodyB.angularVelocity;
    const relativeAngularVelocity = bodyB.angularVelocity - angularVelocityA;

    // Calculate opposing torque
    const dampingTorque = -rotaryDamping * relativeAngularVelocity;

    // Apply opposing torque to both bodies (Newton's third law)
    if (!bodyB.isStatic) {
        bodyB.torque += dampingTorque;
    }
    if (!bodyA.isStatic) {
        bodyA.torque -= dampingTorque;
    }
});

Step 3: Tuning Stability

Because the damping torque accumulates linearly with speed, very high damping values combined with low body inertia can cause numerical instability or oscillation.

To fine-tune performance: