How Does Restitution Control Bounciness in Planck.js?
In Planck.js—a 2D JavaScript physics engine based on Box2D—the restitution property directly determines the elasticity, or “bounciness,” of a rigid body during a collision. This article explores how restitution dictates kinetic energy retention, how the engine calculates bouncing behavior when two objects collide, and how to implement it effectively in your code.
Understanding Restitution in Physics Engines
Restitution is a coefficient that represents the ratio of the relative velocity after a collision to the relative velocity before a collision. In Planck.js, this value is defined on a Fixture object rather than the rigid body itself.
The value is typically constrained between 0.0 and
1.0:
0.0(Inelastic Collision): The object will not bounce at all. It absorbs the impact and immediately stops or slides along the surface (e.g., a lump of clay hitting the floor).1.0(Perfectly Elastic Collision): The object retains 100% of its kinetic energy and bounces back with the exact same speed it had before the impact (e.g., a perfectly bouncy rubber ball).
Values greater than 1.0 are technically possible in the
engine but will add energy to the system, causing the object to bounce
higher with each impact, which violates the laws of physics.
How Planck.js Resolves Multi-Object Collisions
When two fixtures collide, Planck.js must determine a single, combined restitution value for the interaction. Because each fixture has its own independent restitution property, the engine uses a specific formula to calculate the outcome.
By default, Planck.js uses the maximum restitution value of the two colliding shapes. The mathematical representation of this combined mixing formula is:
\[k_r = \max(\text{restitution}_1, \text{restitution}_2)\]
For example, if a bouncy ball with a restitution of 0.8
hits a solid concrete floor with a restitution of 0.0, the
engine will select 0.8 as the final restitution value,
causing the ball to bounce. If you require a different mixing behavior
(such as multiplying the values instead), you can override this globally
or handle it within the engine’s pre-solve contact listeners.
Code Implementation Example
To apply bounciness to an object in Planck.js, you must set the
restitution property inside the fixture definition before
attaching it to a body.
const planck = require('planck-js');
// Create a world
const world = planck.World();
// Create a rigid body
const body = world.createBody({
type: 'dynamic',
position: planck.Vec2(0, 10)
});
// Define the shape and fixture with restitution
const ballShape = planck.Circle(1.0);
body.createFixture({
shape: ballShape,
density: 1.0,
friction: 0.3,
restitution: 0.75 // This sets the bounciness to 75% efficiency
});By adjusting this decimal value on your fixtures, you can easily simulate a wide variety of materials, ranging from heavy, dead weights to highly active, bouncy projectiles.