Simulate Resonance and Structural Failure in Matter.js
This article explains how to build an interactive 2D physics sandbox using Matter.js to visualize harmonic resonance and structural failure modes. By modeling a lattice of rigid bodies connected by elastic, breakable constraints and applying a periodic oscillatory force, you can observe how mechanical systems store energy and catastrophic failure occurs when external driving frequencies match the system's natural frequencies.
1. Setting Up the Matter.js Environment
Begin by initializing the foundational Matter.js modules: the engine, renderer, runner, and world.
const { Engine, Render, Runner, Bodies, Composite, Constraint, Events, Body, Vector } = Matter;
const engine = Engine.create();
const world = engine.world;
const render = Render.create({
element: document.body,
engine: engine,
options: {
width: 800,
height: 600,
wireframes: false
}
});
Render.run(render);
const runner = Runner.create();
Runner.run(runner, engine);2. Constructing the Breakable Structure
A structure such as a bridge, tower, or cantilever is constructed
using an array of rigid nodes (Bodies.circle or
Bodies.rectangle) connected by elastic links
(Constraint.create).
To simulate material limits, assign a custom property—such as
maxElongation or breakingForce—to each
constraint.
function createBeam(bodyA, bodyB, stiffness = 0.05, damping = 0.01) {
const length = Vector.magnitude(Vector.sub(bodyA.position, bodyB.position));
return Constraint.create({
bodyA: bodyA,
bodyB: bodyB,
length: length,
stiffness: stiffness,
damping: damping,
render: {
strokeStyle: '#4a90e2',
lineWidth: 3
},
plugin: {
restLength: length,
maxStrain: 0.25 // Fails at 25% elongation
}
});
}Construct a multi-segment bridge anchored at both ends to static bodies:
const nodes = [];
const segments = 10;
const spacing = 60;
const startY = 300;
for (let i = 0; i <= segments; i++) {
const isAnchor = (i === 0 || i === segments);
const node = Bodies.circle(100 + i * spacing, startY, 6, {
isStatic: isAnchor,
frictionAir: 0.005
});
nodes.push(node);
Composite.add(world, node);
}
const beams = [];
for (let i = 0; i < nodes.length - 1; i++) {
const beam = createBeam(nodes[i], nodes[i + 1]);
beams.push(beam);
Composite.add(world, beam);
}3. Implementing Structural Failure Logic
Matter.js constraints do not break natively. You must inspect
structural strain on every tick using the beforeUpdate
engine event and detach constraints exceeding their failure
threshold.
Events.on(engine, 'beforeUpdate', () => {
for (let i = beams.length - 1; i >= 0; i--) {
const beam = beams[i];
if (!beam.bodyA || !beam.bodyB) continue;
const currentLength = Vector.magnitude(
Vector.sub(beam.bodyA.position, beam.bodyB.position)
);
const strain = Math.abs(currentLength - beam.plugin.restLength) / beam.plugin.restLength;
// Visual stress indication: Interpolate color based on strain
if (strain > beam.plugin.maxStrain * 0.7) {
beam.render.strokeStyle = '#e74c3c'; // Warning: near failure
}
// Failure condition
if (strain > beam.plugin.maxStrain) {
Composite.remove(world, beam);
beams.splice(i, 1); // Remove from tracking array
}
}
});4. Applying Harmonic Forcing for Resonance
Resonance occurs when an external periodic force matches the natural frequency of the physical system. Model this by applying a sinusoidal force vector to a central node.
let time = 0;
const targetNode = nodes[Math.floor(nodes.length / 2)];
const drivingFrequency = 0.05; // Adjust to match natural frequency
const forceAmplitude = 0.004;
Events.on(engine, 'beforeUpdate', (event) => {
time += event.delta * 0.001; // Convert delta to seconds
if (targetNode && !targetNode.isStatic) {
const forceMagnitude = Math.sin(2 * Math.PI * drivingFrequency * time) * forceAmplitude;
Body.applyForce(targetNode, targetNode.position, {
x: 0,
y: forceMagnitude
});
}
});5. Analyzing Structural Failure Modes
By adjusting the drivingFrequency and
forceAmplitude, you can trigger distinct modes of
structural collapse:
- Fundamental Mode (First Harmonic): A low-frequency drive matches the global swing of the structure, concentrating maximum tension at the anchor points. Anchors fail first, leading to immediate complete collapse.
- Higher Harmonics: Increasing the frequency creates standing waves with stationary nodes and dynamic antinodes. Breakage occurs mid-span where localized shear and bending strain peak.
- Cascade/Progressive Collapse: Once a single constraint snaps, the tension redistributes instantaneously to adjacent constraints, driving their strain beyond the failure threshold and triggering an unzipping effect across the lattice.