Implement Base Isolation Dampers in Matter.js
This article explains how to simulate seismic base isolation systems beneath multi-story structures using Matter.js. By decoupling a building from ground motion using a combination of flexible constraints, linear damping, and kinematic ground drivers, you can replicate how elastomeric bearings and friction dampers absorb lateral earthquake energy. The following sections walk through the mechanics, configuration properties, and code implementation required to build a functional, sway-reducing 2D physics simulation.
The Physics of Base Isolation in 2D
Base isolation protects structures by lengthening their natural vibration period and dissipating kinetic energy before it propagates upward. In Matter.js, simulating this involves three core layers:
- The Ground Foundation: A kinematic body driven laterally by a periodic function to simulate horizontal earthquake waves.
- The Isolation Interface: Horizontal sliders or spring-damper constraints that allow controlled lateral movement while supporting vertical loads.
- The Superstructure: A rigid or semi-flexible assembly of dynamic bodies representing building floors and structural columns.
Step 1: Setting Up the Simulation World
Initialize the standard Matter.js engine, renderer, and runner modules.
const { Engine, Render, Runner, Bodies, Composite, Constraint, 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);Step 2: Creating the Ground and Seismic Excitation
Create a base plate that acts as the moving bedrock. Mark it as
isKinematic (or isStatic updated manually via
position) so it carries infinite mass and ignores forces exerted by the
building above.
const ground = Bodies.rectangle(400, 550, 600, 40, {
isStatic: true,
render: { fillStyle: '#2c3e50' }
});
Composite.add(world, ground);
// Drive the ground with sinusoidal lateral displacement
let time = 0;
const earthquakeFrequency = 0.05;
const earthquakeAmplitude = 8;
Matter.Events.on(engine, 'beforeUpdate', () => {
time += 1;
const targetVelocityX = Math.cos(time * earthquakeFrequency) * earthquakeAmplitude;
Body.setVelocity(ground, { x: targetVelocityX, y: 0 });
Body.setPosition(ground, {
x: 400 + Math.sin(time * earthquakeFrequency) * (earthquakeAmplitude / earthquakeFrequency),
y: 550
});
});Step 3: Designing the Base Isolation Dampers
To construct an elastomeric lead-rubber bearing equivalent, couple the ground to an isolated base slab using two components: a rigid support boundary to carry the vertical load and non-rigid constraints that control horizontal stiffness and energy dissipation.
Matter.js provides stiffness and damping
properties directly within constraints:
stiffness: Dictates the restoring force. Low stiffness decouples the building from high-frequency ground accelerations.damping: Absorbs kinetic energy and dissipates oscillations over time.
// Base slab of the building resting above the ground
const baseSlab = Bodies.rectangle(400, 500, 200, 20, {
density: 0.005,
render: { fillStyle: '#7f8c8d' }
});
// Left Damper Constraint
const damperLeft = Constraint.create({
bodyA: ground,
pointA: { x: -80, y: -20 },
bodyB: baseSlab,
pointB: { x: -80, y: 10 },
stiffness: 0.05,
damping: 0.1,
render: { strokeStyle: '#e74c3c', lineWidth: 5 }
});
// Right Damper Constraint
const damperRight = Constraint.create({
bodyA: ground,
pointA: { x: 80, y: -20 },
bodyB: baseSlab,
pointB: { x: 80, y: 10 },
stiffness: 0.05,
damping: 0.1,
render: { strokeStyle: '#e74c3c', lineWidth: 5 }
});
Composite.add(world, [baseSlab, damperLeft, damperRight]);Step 4: Constructing the Building Superstructure
Stack several floor slabs connected by structural columns above the base slab. Using semi-stiff constraints to connect the superstructure components allows you to visually observe story drift and inter-story shear forces.
const floors = [];
const numFloors = 4;
const floorHeight = 60;
let previousFloor = baseSlab;
for (let i = 0; i < numFloors; i++) {
const yPos = 500 - (i + 1) * floorHeight;
const floor = Bodies.rectangle(400, yPos, 160, 15, {
density: 0.002,
render: { fillStyle: '#34495e' }
});
// Vertical structural columns (stiff connections)
const leftColumn = Constraint.create({
bodyA: previousFloor,
pointA: { x: -70, y: -10 },
bodyB: floor,
pointB: { x: -70, y: 10 },
stiffness: 0.9,
render: { strokeStyle: '#95a5a6', lineWidth: 3 }
});
const rightColumn = Constraint.create({
bodyA: previousFloor,
pointA: { x: 70, y: -10 },
bodyB: floor,
pointB: { x: 70, y: 10 },
stiffness: 0.9,
render: { strokeStyle: '#95a5a6', lineWidth: 3 }
});
// Cross-bracing to prevent column shear collapse
const crossBrace = Constraint.create({
bodyA: previousFloor,
pointA: { x: -70, y: -10 },
bodyB: floor,
pointB: { x: 70, y: 10 },
stiffness: 0.7,
render: { strokeStyle: '#bdc3c7', lineWidth: 1 }
});
Composite.add(world, [floor, leftColumn, rightColumn, crossBrace]);
previousFloor = floor;
}Tuning Damper Performance
To verify the damper's effectiveness, compare the top floor's lateral displacement against the ground motion.
- If the building tops over or resonates violently, decrease
stiffness(e.g., from0.05down to0.01) to shift the structure's resonance away from the ground excitation frequency. - If the base slab collides with motion boundaries or oscillates
indefinitely, increase the
dampingproperty (e.g., up to0.2or0.3) to dissipate the energy faster. - Ensure constraint length remains close to the actual rest distance between points; non-zero resting lengths in dynamic configurations can cause vertical bouncing.