Professional Documents
Culture Documents
Huamin Wang
The motion of a rigid body contains two parts: linear motion and angular motion. In this docu-
ment, we will study both motions. We will also discuss how to detect collisions and estimate collision
responses. To simplify our notations, we will follow the standard formats: bold fonts are vectors,
italic fonts are scalars, and UPPERCASES are matrices.
The physics quantities associated with linear motion are: position, velocity, force, ... The physics
quantities associated with angular motion are: orientation, angular velocity, torque, ...
1 Linear Motion
Let us first examine the linear motion of a rigid body. Without considering the orientation, this is
equivalent to simulating the motion of the body mass center x(t), which changes as a function of
time t. Assuming that the initial model is centered at the origin as shown in Figure 1a. We can
simply treat x(t) as the position of the rigid body. To model the linear motion, we also define the
derivative of x(t) to time t, which is commonly known as the linear velocity v(t).
To animate the linear motion, our goal is to update the position and the velocity of the center,
each time the Update function gets called. Let the time of the last Update call be t0 and the time of
the current call be t1 . The time difference ∆t = t1 − t0 is known as the time step. Given the position
and the velocity at t0 , we calculate the new position and the new velocity as:
( R t1
1
v(t1 ) = v(t0 ) + M f (t)dt ≈ v(t0 ) + ∆tf (t0 )/M,
R t1 t0 (1)
x(t1 ) = x(t0 ) + t0 v(t)dt ≈ x(t0 ) + ∆tv(t1 ),
in which M is the mass of the object and f (t0 ) is the total force evaluated at time t0 . If we assume
that the mass distributed at each vertex i is mi , the total mass is simply their sum:
X
M= mi . (2)
i
Note that Equation 6 is just an approximation. Formally, this is called explicit time integration. We
will discuss other time integrators later.
One question here is how to evaluate f (t0 ). This vector represents the total force applied on the
whole rigid body. It contains the gravity force f gravity (t0 ) = M g, where g = [0, −9.8m/s2 , 0] is the
gravity acceleration. It contains other forces as well, such as the collision force. Many simulators
also model the damping effect by some damping force. Let us do not do this for now.
2 Angular Motion
To simulate the angular motion of a rigid body, we must define everything in an angular way.
2.1 Quaternion
The first and foremost question is how to define the orientation, i.e., “angular position”. One idea
is to use the matrix. However, only an orthonormal matrix can be a rotational matrix and we must
keep enforcing the orthonormality, which is not very convenient. Alternatively, we can define a bunch
1
ܘ
ܚ
ܠሺݐሻ
ܘ ۼ
ܘ
ܚ ሺݐሻ ܚ ሺݐሻ
ܠሺݐሻ ܠሺݐሻ+ܚ ሺݐሻ
ܠሺݐሻ ܠሺݐሻ+ܚ ሺݐሻ ܠሺݐሻ+ܚ ሺݐሻ
ܞሺݐሻ+࣓ሺݐሻ ൈ ܚ ሺݐሻ
of rotation angles around X, Y, and Z axes, known as Euler angles. Again, that is not easy to derive
the formula for their time evolution.
Our solution is to use quaternion. A quaternion is a 4D vector q = [x, y, z, w], or q = [v, w], which
contains a 3D vector v and a scalar w. A quaternion must be normalized:
x2 + y 2 + z 2 + w2 = 1. (3)
A quaternion represents a rotation around axis v with an angle θ, such as w = cos(θ/2) and x2 +
y 2 + z 2 = sin2 (θ/2). A quaternion can be converted into a rotation matrix as:
2
w + x2 − y 2 − z 2
2(xy − wz) 2(xz + wy)
R= 2(xy + wz) w 2 − x2 + y 2 − z 2 2(yz − xw) . (4)
2(xz − wy) 2(yz + xw) 2 2
w −x −y +z 2 2
Compared with a rotational matrix, a quaternion is very easy to maintain: we just have to make it
normalized all the time.
Quaternion arithmetic is defined as follows. Let q1 = [v1 , w1 ] and q2 = [v2 , w2 ] be two quaternion
vectors and s be a scalar. We have:
q1 + q2 = [v1 + v2 , w1 + w2 ],
sq1 = [sv1 , sw1 ], (5)
q1 q2 = [w1 v2 + w2 v1 + v1 × v2 , w1 w2 − v1 · v2 ].
where ω̂ = [ω, 0] is a quaternion extended from ω and ω̂(t1 )q(t0 ) is the product of two quaternions.
The 3D vector ω(t) is the angular velocity. Its direction represents the angular velocity axis and
its magnitude represents the rotation speed. The matrix I−1 (t) is the body inertia. Like the mass,
the inertia indicates the resistance of the body to rotational motion. But unlike the mass, the inertia
2
is not constant. Intuitively, when a body rotates, its resistance to the rotation around X, Y, Z axes
will also change. So we must update the inertia as a function of time:
where R(t) is the rotational matrix calculated using the quaternion q(t) at time t, and Ibody is the
inertia in the original configuration:
X
Ibody = (pTi pi )1 − pi pTi .
(8)
i
Here pi the original position of a vertex i and 1 is the 3-by-3 identity matrix.
Now the only question is: how to evaluate the torque τ (t0 ) at time t0 ? Let fi (t) be the force
applied at an individual vertex i, we calculate the torque as:
X X
τ (t0 ) = ri (t) × fi (t) = (R(t)pi ) × fi (t), (9)
i i
where ri (t) is the vector from the center to vertex i, after the body is rotated as shown in Figure 1b.
Note that we do not need to consider the gravity force in angular motion. This is because the gravity
should not cause the body to spin. Mathematically, this implies the torques caused by the gravity
are summed to zero.
3 Collision Handling
To make rigid body simulation interesting, we must use interesting forces, specially the force caused
by collision. To begin with, let us consider the status a vertex i shown in Figure 1c. Its position
at time t is x(t) + ri (t), and its velocity at time t is: vt + ω(t) × ri (t), where ri (t) = R(t)pi is the
vector from the center to i. We claim that the vertex is in collision with the floor, if two conditions
are satisfied:
• a. Its position xi (t) is below the ground floor: y = 0.
• b. Its velocity vi (t) is still going down.
Let N = [0, 1, 0] be the upward vector. We formulate the two conditions as:
xi (t) · N = (x(t) + ri (t)) · N < 0,
(10)
vi (t) · N = (vt + ω(t) × ri (t)) · N < 0.
By testing these two conditions, we can know if vertex i is in collision at time t.
vinew (t) = vnew (t) + ω new (t) × ri (t) = vi (t) − (µ + 1) (vi (t) · N) N. (11)
3
To achieve vnew (t) and ω new (t), we assume that there is a sudden but unknown impulse j applied at
vertex i and it causes the following changes to the velocities:
new
v (t) = v(t) + j/M,
(12)
ω new (t) = ω(t) + I−1 (t) (ri (t) × j) .
j/M + I−1 (t) (ri (t) × j) × ri (t) = −(µ + 1) (vi (t) · N) N. (13)
To solve Equation 13, we propose to define the cross product by a matrix product:
0 −riz riy
ri (t) × j = R∗i j = riz 0 −rix j, (14)
−riy rix 0
and we can then solve j using the inverse of the matrix K. Once we get j, we use it to update v(t)
and ω(t) respectively. That concludes our collision handling process.
4 Pseudo Code
The code assumes that constant variables have already been defined, including ∆t, M and Ibody .
4
Algorithm 1 Update()
v ← v + ∆tg; . Update velocities
v ← clinear v;
ω ← cangular ω;
Collision Handler(); . Apply collision responses to velocities
x ← x + ∆tv; . Update position and orientation
q ← q + 12 ∆t[ω, 0]q;
q ← q/ kqk;
transform.position ← x; . Assign to mesh
transform.rotation ← q;