Transform inertia tensor using quaternion

I have inertia tensor T in body coordinates and quaternion q for the body. I know I can transform T to world coordinate by converting quaternion to rotation matrix R and then use the relation (R * T * R^T). However this seems unnecessarily expensive and unwieldy (especially if you are doing this often).

So my question is:

How do I transform inertia tensor from body to world coordinate directly using quaternion and without having to generate rotation matrix from quaternion?

• Out of interest and a need for context, why would you want to transform your inertia tensor? – Ian Young May 9 '17 at 9:03
• You need to do that when computing new angular velocity in collision response: – Shital Shah May 9 '17 at 9:38
• It's been a while since I looked at angular kinematics, but that doesn't sound right. I don't think you should be modifying the inertia tensor at all. – Ian Young May 9 '17 at 9:57
• See eq (5) at en.wikipedia.org/wiki/…. The inertia tensor I here is in world frame which requires transformation. – Shital Shah May 11 '17 at 20:46

I finally found the answer in this document. The idea is that you can indeed define multiplication of quaternion and matrix as follows: Take 4x4 matrix M and view each of its column as quaternion m_j. Now you can define q.M by multiplipliting two quaternions q and m_j and putting the result quaternion as jth column in to 4x4 result matrix. Now to tranform inertia matrix J from body frame to world frame using quaternion q, one can use following relationship:

(q.(q.J.q*)^T).q*)^T

One step I'm hazzy about is how do you convert inertia matrix from 3x3 to 4x4. My assumption is that you do this simply by inserting 1 in extra diagonal element and everything else 0. This extra 1 would correspond to same location as w component of q. I haven't tested this yet.

• The extra information in the mat4 is for translation (4th column), which should be {0,0,0,1}. – Ian Young May 16 '17 at 10:13
• Thanks for sharing that paper. Two notes on the paper: they use 4x4 matrices with a "leading" 1 not a trailing as shown on page 2. (q.(q.J.q*)^T).q*)^T is easily explained by them as ... the tensor A is rotated, at first, by rotating quaternions across each column ..., and at second, by rotating quaternions across each row ... – Christoph Apr 5 '18 at 11:26

3D Physics computations are messy and unwieldy. There is no avoiding that.

However, you still have a couple of choices, once you are comfortable bouncing between coordinate systems.

1. Compute your impulses locally, which means inertia tensor never needs to be changed. To do this means transforming contact points to local space for each body.

M = inv(M), cpLocal = M * cp, J = compute impulse, W += I * J

1. Compute your impulses in world space, then transform then to local space for each body. This means taking the inverse of your model transform and multiplying the impulse by it.

Mi = mat3( inv( M ) ), Jlocal = Mi * J, W += I * Jlocal

1. Compute in world space, and transform the inertia tensor to world space then use that to adjust the angular effects. This is :

M3I = M3( rot_toM4 ) * I, W += M3I * J

I will point out, by the way, that many engines do not try to model the inertia of a shape perfectly, and will fudge the numbers, so no rotation of the inertia tensor is necessary.