A capsule is defined by two hemispheres and a cylinder. Capsules are pretty useful geometry for collision detection since they are easily defined mathematically (implicitly defined). This means that minimal information can be stored in memory to represent a capsule in 3D space. Given a radius value and position information only a few floating point values are necessary. Algorithms like GJK also work well with implicitly defined shapes since support mappings can be computed in constant time.

Given the inertia tensor of a cylinder and sphere the inertia tensor of a capsule can be calculated with the help of the parallel axis theorem. The parallel axis theorem can shift the origin that an inertia tensor is defined relative to, given just a translation vector. We care about the tensor form of the parallel axis theorem since it is probably easiest to understand from a computer science perspective:

J is the final transformed inertia. I is the initial inertia tensor. m is the mass of the object in question. R is the translation vector to shift with. E3 is the standard basis, or the identity matrix. The cross symbol is the outer product (see next paragraph).

Assuming readers are familiar with the dot product and outer product, computing the change in an inertia tensor isn’t too difficult.

The center of mass of a hemisphere is 3/8 * radius above the center of the spherical base. Knowing this and understanding the parallel axis theorem, the inertia tensor of one of the hemispheres can be easily calculated. My own derivation brought me the conclusion that the inertia tensor of a translated along the y axis towards the cylinder base is:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
float r2 = radius * radius; float l = length; // length is the height of the cylinder float l2 = length * length; // Hemisphere moment of inertia about C.O.M. at origin float moment = 2.0f / 5.0f * mass * r2 * r2; // Parallel axis by half the cylinder height float x = moment + 1.0f / 4.0f * mass * l2; // Parallel axis to the C.O.M. of the hemisphere at end of cylinder x += 3.0f / 8.0f * mass * r2; float y = moment; float z = x; // Final inertia tensor I for a single shifted hemisphere [ x, 0, 0 ] [ 0, y, 0 ] [ 0, 0, z ] // We can add I with the tensor J, where J is the inertia of a cylinder final = J + 2.0f * I |

Please note the final inertia tensor assumes the capsule is oriented such that the cylinder is aligned along the y axis. A rotation matrix R can be used to transform the final inertia tensor I into world space like so: R * I * R^T. To learn why this form is used read this post.

I’m not entirely sure if this is correct in execution, but the theory of applying the parallel axis theorem in this way is definitely correct. I computed the parallel axis theorem on paper without a calculator all pretty late in the night. If anyone goes through the derivation and cares to leave a comment pointing out any mistakes I’d appreciate it!