Prevent Particle Jamming in Matter.js Funnels
Simulating thousands of small circular bodies passing through a narrow funnel in Matter.js often leads to particle jamming, clustering, and performance bottlenecks. This issue occurs due to physical arch formation, friction, uniform particle sizing, and solver constraints within the physics engine. You can eliminate jamming and maintain smooth particle flow by introducing polydispersity, minimizing friction coefficients, optimizing funnel geometry, applying external agitation, and tuning the engine's solver parameters.
Introduce Particle Polydispersity
Monodisperse particles—where every circle has the exact same radius—naturally self-assemble into rigid, crystalline lattices. When approaching a bottleneck, these uniform structures form mechanical arches over the opening that block subsequent particles.
To prevent this:
- Vary the radii of your particles by ±10% to ±20%.
- Implement a random distribution function during particle generation
(e.g.,
radius = baseRadius * (0.85 + Math.random() * 0.3)). - The resulting size variation (polydispersity) disrupts stable arch formation and causes the aggregate mass to behave more like a fluid.
Reduce Friction Parameters
Matter.js assigns default friction values that encourage sticking. When thousands of bodies exert pressure downward, standard friction values allow stable bridges to hold the weight of the particles above them.
Adjust the particle and funnel bodies with the following properties:
- Set
friction: 0.0or a very low value (e.g.,0.001). - Set
frictionStatic: 0.0to eliminate static resistance that triggers bridging. - Set
frictionAir: 0.01to prevent particles from gaining excessive, unstable speeds while removing surface drag.
Optimize Funnel Geometry
The physical design of the constriction strongly influences whether particles funnel smoothly or form bottlenecks.
- Increase the Outlet Width: Ensure the funnel opening is at least 3 to 5 times larger than the diameter of your largest particle. Anything narrower physically promotes mechanical interlocking.
- Steepen Wall Angles: Funnels with shallow angles allow particles to settle along the edges. Maintain a steep wall angle, ideally 60 degrees or steeper relative to the horizontal axis.
- Add Chamfers and Curved Corners: Sharp interior corners where the funnel slopes meet the vertical neck create catch points. Use multiple angled segments to create a rounded transition into the outlet.
Implement Dynamic Agitation
Industrial hoppers rely on vibration to disrupt jams, and the same principle applies in Matter.js:
- Micro-Vibrations: Apply tiny, randomized forces or
gentle periodic oscillations to particles near the funnel neck using
Matter.Body.applyForce(). - Shaking the Funnel: Gently oscillate the funnel walls left and right using a small sine wave applied directly to their position.
- Agitator Pins: Place a static or slowly rotating circular obstacle (a deflector peg) slightly above the funnel throat. This splits the main downward flow into two separate streams, reducing the downward pressure directly above the exit and preventing central arching.
Tune Matter.js Engine Iterations
Simulating thousands of dynamic bodies pushes 2D physics engines to their limits, occasionally causing overlapping bodies or incorrect contact resolution that mimics jamming.
- Adjust Solver Iterations: Lower
engine.positionIterationsandengine.velocityIterationsif the frame rate drops, or raise them slightly (e.g., to 8–10) if particles tunnel into one another and stick. - Use Fixed Substepping: When dealing with high
particle counts, update the engine using a fixed delta time
(
Matter.Engine.update(engine, 1000 / 60)) to maintain numerical stability and avoid sudden physics spikes that freeze flow.