Articulated Crane Boom with Winch in Matter.js

This guide explains how to construct an articulated crane boom featuring a functional, cable-winched hook using the Matter.js 2D physics engine. You will learn how to connect multi-part rigid bodies using revolute constraints, actuate joints, and dynamically adjust constraint lengths in real time to simulate winding and unwinding a cable around a winch drum.

Core Architecture

Building an articulated crane requires two distinct physical systems:

  1. The Articulated Boom: A series of rigid rectangular bodies linked end-to-end via hinge (revolute) constraints.
  2. The Winch and Hook System: A dynamic body representing the hook suspended from the boom tip via an adjustable distance constraint representing the cable.

1. Setting Up the Boom Segments

The crane arm consists of a static base and dynamic arm segments connected by pin constraints.

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

const engine = Engine.create();
const world = engine.world;

// Create the anchor base
const base = Bodies.rectangle(200, 500, 60, 40, { isStatic: true });

// Create boom segments
const boomLower = Bodies.rectangle(260, 420, 150, 20, { 
    collisionFilter: { group: -1 } 
});
const boomUpper = Bodies.rectangle(380, 350, 140, 16, { 
    collisionFilter: { group: -1 } 
});

// Pin lower boom to base
const baseJoint = Constraint.create({
    bodyA: base,
    pointA: { x: 0, y: -20 },
    bodyB: boomLower,
    pointB: { x: -65, y: 0 },
    stiffness: 1,
    length: 0
});

// Articulation joint between lower and upper boom
const elbowJoint = Constraint.create({
    bodyA: boomLower,
    pointA: { x: 65, y: 0 },
    bodyB: boomUpper,
    pointB: { x: -60, y: 0 },
    stiffness: 1,
    length: 0
});

Composite.add(world, [base, boomLower, boomUpper, baseJoint, elbowJoint]);

Assigning a negative collisionFilter.group prevents boom segments from colliding with each other while maintaining collisions with external objects.


2. Implementing the Winch Cable and Hook

The cable is modeled as an elastic distance constraint. The winch effect is achieved by dynamically incrementing or decrementing the constraint's length property during the engine update loop.

// Hook payload
const hook = Bodies.rectangle(440, 450, 20, 20, {
    density: 0.005,
    frictionAir: 0.01
});

// Winch cable constraint
const cable = Constraint.create({
    bodyA: boomUpper,
    pointA: { x: 60, y: 0 }, // Tip of the upper boom
    bodyB: hook,
    pointB: { x: 0, y: -10 },
    stiffness: 0.9,
    damping: 0.1,
    length: 100
});

Composite.add(world, [hook, cable]);

3. Controlling Boom Articulation and Winch Operation

You can actuate the boom segments using angular velocity or applied torque, while winching is controlled by modulating cable.length.

const WINCH_SPEED = 2;
const MIN_CABLE_LENGTH = 20;
const MAX_CABLE_LENGTH = 300;

function handleControls(inputs) {
    // Boom elevation (rotate lower boom)
    if (inputs.boomUp) {
        Matter.Body.setAngularVelocity(boomLower, -0.02);
    } else if (inputs.boomDown) {
        Matter.Body.setAngularVelocity(boomLower, 0.02);
    }

    // Elbow articulation (rotate upper boom)
    if (inputs.elbowUp) {
        Matter.Body.setAngularVelocity(boomUpper, -0.02);
    } else if (inputs.elbowDown) {
        Matter.Body.setAngularVelocity(boomUpper, 0.02);
    }

    // Winch controls: Reel in
    if (inputs.reelIn && cable.length > MIN_CABLE_LENGTH) {
        cable.length -= WINCH_SPEED;
    }

    // Winch controls: Reel out
    if (inputs.reelOut && cable.length < MAX_CABLE_LENGTH) {
        cable.length += WINCH_SPEED;
    }
}

4. Preventing Instability and Stretching

High-load constraint systems in Matter.js can suffer from elasticity and joint separation under heavy payloads. To stabilize the assembly: