Simulating Granular Avalanches in Matter.js
This guide explains how to model granular avalanches down an inclined plane using the Matter.js 2D physics engine. By generating an ensemble of polydisperse rigid circular bodies (discs) and placing them on an angled static boundary, you can recreate the micro-mechanical interactions that lead to macroscopic granular flow, jamming transitions, and angle-of-repose phenomena. The following sections walk through setting up the simulation environment, configuring critical contact physics, and executing the simulation code.
1. Setting Up the Matter.js Environment
A granular avalanche model requires an active physics engine, a rendering context, and a continuous update loop. Import Matter.js and initialize the core modules:
const { Engine, Render, Runner, Bodies, Composite, Body } = 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,
background: '#111'
}
});
Render.run(render);
const runner = Runner.create();
Runner.run(runner, engine);2. Creating the Inclined Plane and Basin
The geometry consists of a titled ramp, an optional release gate to hold the material before triggering the avalanche, and a horizontal collection floor at the base.
const rampAngle = Math.PI / 6; // 30 degrees inclination
// Inclined plane
const ramp = Bodies.rectangle(300, 300, 500, 20, {
isStatic: true,
angle: rampAngle,
render: { fillStyle: '#444' }
});
// Flat basin floor at the bottom
const floor = Bodies.rectangle(400, 580, 800, 40, {
isStatic: true,
render: { fillStyle: '#333' }
});
// Temporary gate to hold particles before release
const gate = Bodies.rectangle(430, 360, 20, 120, {
isStatic: true,
angle: rampAngle - Math.PI / 2,
render: { fillStyle: '#888' }
});
Composite.add(world, [ramp, floor, gate]);3. Tuning Granular Material Properties
The behavior of granular media depends heavily on surface friction and restitution (bounciness). Grains in real avalanches exhibit low restitution and moderate-to-high surface friction, which dampens kinetic energy through collisions:
friction(Coulomb Friction): Controls dynamic sliding resistance. Typical values range between0.3and0.8.frictionStatic: Prevents movement until shear stress exceeds the threshold, allowing natural heaps and an angle of repose to form.restitution: Should be kept very low (0.0to0.1) to mimic inelastic collisions common in sand, gravel, or snow.- Polydispersity: If all discs have identical radii, they form regular crystalline lattices that slide unrealistically. Varying the particle radii by 10% to 20% introduces disorder and mimics real granular material.
4. Spawning the Granular Discs
Generate a cluster of small circular bodies uphill behind the gate:
const particles = [];
const rows = 15;
const cols = 15;
const baseRadius = 6;
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
// Introduce random radius variation (polydispersity)
const radius = baseRadius + (Math.random() * 2 - 1) * 1.5;
// Position the stack on the upper section of the slope
const x = 150 + i * (baseRadius * 2 + 1);
const y = 100 + j * (baseRadius * 2 + 1);
const particle = Bodies.circle(x, y, radius, {
friction: 0.5,
frictionStatic: 0.8,
restitution: 0.05,
density: 0.002,
render: {
fillStyle: '#e0a96d'
}
});
particles.push(particle);
}
}
Composite.add(world, particles);5. Triggering the Avalanche
To initiate the avalanche, remove the static gate after the particles have settled under standard gravity.
// Remove the gate after 2 seconds to release the flow
setTimeout(() => {
Composite.remove(world, gate);
}, 2000);6. Engine Considerations for High Particle Counts
Simulating hundreds of interacting discs can stress the collision detector. To optimize accuracy and stability:
- Increase Position and Velocity Iterations: If
particles tunnel through the inclined plane or through each other,
increase solver precision via
engine.positionIterations = 10;andengine.velocityIterations = 8;. - Adjust Sub-stepping: For high-velocity flows down steep slopes, run the engine update step at a smaller, fixed delta time to eliminate overlap errors.