Constrained Dynamics (I)
I am starting a mini-series of posts that go through the mathematical derivation necessary to build a minimal physics engine with support for constrained dynamics.
This first post is about unconstrained dynamics, using a free-falling particle as an example.
Upcoming posts will describe constrained dynamics, then build a (single-constraint) pendulum, and finally a (multi-constraint) double-pendulum.
We will restrict ourselves to:
- 2D.
- Only one particle mass.
- Only one external force (gravity).
- Only one type of constraint (distance).
Rigid bodies with a surface area, collisions, contacts, frictions, etc… will be left out of the picture.
Incredibly useful links
This mini-series is nothing but a digest of knowledge that can be found in great detail here:
- Erin Catto’s Box2D publications area.
- Physically Based Modeling: Principles and Practice by Andrew Witkin and David Baraff.
In particular:
- This presentation by Erin Catto.
- These lecture notes by Andrew Witkin.
Unconstrained dynamics
By way of newtonian mechanics:
- 1st Law: The velocity (or lack thereof) of a particle remains unchanged until a force is applied to it.
- 2nd Law: When a force is applied to a particle, it experiments an acceleration of magnitude
in the direction of .
As a consequence of the 1st Law, we can describe the state
As a consequence of the 2nd Law, we can’t consider acceleration to be part of the state as it only spawns for as long as an external force is applied to the particle. Force (acceleration) is actually the only agent that causes changes of state.
These three magnitudes are 2D vectors. We will use the following notation:
Momentum
Mass and velocity together lead to the definition of linear momentum:
Another way to read the 2nd Law is that a force acting on a particle induces a change on its momentum.
We can reason that momentum is a measure of the impulse (force over time) that one must exert in order to stop the particle (i.e., cancel out its current velocity).
For a steady force, this is:
State over time
The evolution of the particle’s position is so ruled by the differential equation:
Which can be read as: the particle position is a function of the initial state
The classic and most intuitive way to iteratively solve the above diffential equation is the Semi-Implicit Euler method:
Where each iteration is meant to encompass a discrete time slice of duration
These expressions can be read as:
- Calc the acceleration caused by the total sum of applied forces at time
. - Update the particle’s velocity with said acceleration (times
). - Update the particle’s position with the updated velocity (times
).
The intricacies of numerical solvers for differential equations are outside the scope of this post. But the above method does a fine job at producing a discrete approximation to the true state over time. At least, as long as
Note that the smaller the
Free-fall (iterative)
We’re only considering gravity in this post (
Here’s a simple implementation for the particle state and the simulation step:
struct particle_t
{
explicit particle_t() : m( 1 ), p( 0 ), v( 0 ) {}
void step( const f64_t dt, const vec2d_c& F )
{
const vec2d_c a = ( F / m );
v += ( a * dt );
p += ( v * dt );
}
f64_t m; // Mass.
vec2d_c p; // Position.
vec2d_c v; // Velocity.
};
Here’s a humble animation of the particle in free-fall:
If we give an initial velocity to the particle (
Free-fall (analytic)
Differential equations are outside the scope of this post. But let’s say at least that an analytic solution to this example, where there’s only one steady external force, is possible and easy.
The analytic solution gives us a function that explicitly describes the position of the particle at any given time. This sounds better than an iterative simulation, although analytic solutions are untractable in non-trivial systems.
The vertical force that gravity exerts on a particle is proportional to its mass, which in turn makes gravity accelerate any particle the same regardless of its mass:
Plugging
Which analytic solution is the very familiar projectile motion formula:
This type of motion is also called parabolic throw. As can be seen both in the above animation and by looking at the formula, the ballistic trajectory w.r.t. time is horizontally linear, and vertically parabolic.
Things are about to get exciting. I promise!