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:
- The Articulated Boom: A series of rigid rectangular bodies linked end-to-end via hinge (revolute) constraints.
- 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:
- Increase Solver Iterations: Increase
engine.positionIterationsandengine.velocityIterationsto8or10(default is6and4). - Manage Mass Ratios: Ensure the hook and payload masses do not drastically exceed the mass of the boom segments.
- Limit Winch Limits: Enforce strict minimum and
maximum boundaries on
cable.lengthto avoid zero-division errors or physics glitches when completely retracted.