How it works

Each ball is modelled as a rigid disk with mass proportional to its area:

$$m = \pi r^2$$

Euler integration

Position and velocity are updated each frame using Euler integration with timestep $\Delta t$:

$$\mathbf{v}_{n+1} = \mathbf{v}_n + \mathbf{g} ,\Delta t$$

$$\mathbf{x}_{n+1} = \mathbf{x}_{n} + \mathbf{v}_{n+1} ,\Delta t$$

where $\mathbf{g} = (0, g)$ is the gravity vector (positive $y$ points down on screen).

Collision detection

Two balls $A$ and $B$ with radii $r_A$, $r_B$ and centres $\mathbf{x}_A$, $\mathbf{x}_B$ are overlapping when:

$$|\mathbf{x}_B - \mathbf{x}_A| < r_A + r_B$$

The collision normal is the unit vector pointing from $A$ to $B$:

$$\hat{\mathbf{n}} = \frac{\mathbf{x}_B - \mathbf{x}_A}{|\mathbf{x}_B - \mathbf{x}_A|}$$

Impulse resolution

The relative velocity along the normal tells us whether the balls are approaching:

$$v_\text{rel} = (\mathbf{v}_A - \mathbf{v}_B) \cdot \hat{\mathbf{n}}$$

If $v_\text{rel} \leq 0$ the balls are separating — no impulse needed. Otherwise, the scalar impulse magnitude is:

$$j = \frac{-(1 + e), v_\text{rel}}{\dfrac{1}{m_A} + \dfrac{1}{m_B}}$$

where $e \in [0, 1]$ is the coefficient of restitution — the ratio of post-collision to pre-collision relative speed. $e = 1$ is perfectly elastic (no energy lost), $e = 0$ is perfectly inelastic.

Velocities are updated by applying equal and opposite impulses:

$$\mathbf{v}_A \mathrel{+}= \frac{j}{m_A}\hat{\mathbf{n}}, \qquad \mathbf{v}_B \mathrel{-}= \frac{j}{m_B}\hat{\mathbf{n}}$$

Kinetic energy

The total kinetic energy displayed in the stats bar is:

$$E_k = \sum_i \frac{1}{2} m_i |\mathbf{v}_i|^2$$

Watch it drop immediately after the “Explode” burst as restitution dissipates energy through wall and ball-ball collisions.


Simulation

12
600
0.80
18
KE: — Collisions: 0 fps: —

Controls reference

Control Effect
Balls Number of rigid disks spawned
Gravity Downward acceleration in px/s²
Restitution Energy retained per collision (1 = elastic, 0 = inelastic)
Ball size Radius in pixels — also scales mass as πr²
Respawn Randomise positions and velocities
Explode Apply outward impulse from centre