Sign in to follow this  
Rendaw

Transforming the inertia vector

Recommended Posts

Rendaw    150
I am writing a quick rigid body simulation based on the papers by Baraff and Hecker. I have coded matrix classes in the past and have since transitioned to quaternions to represent rotations. Now, in the rigid body simulation, the inertia tensor for many solids is represented as a scaling matrix. This is then rotated by the body orientation to find the world-oriented inertia tensor. Because the scaling matrix is a value for each axis, I represent it as a 3-vector. I also saw this in another post about quaternions and inertia, but no information on rotating it. Obviously I can't rotate it with a quaternion (for one thing: it can produce zeros on axes), but I don't want to code a matrix class specifically for this. I have no other use for matricies. Is there some other way to rotate the original inertia? --- If I am to multiply the Matrix-form of my orientation quaternion by the inertia, and then that by a column vector, I get this: Is there another way? I did this symbolicly, and got a form of the transformed inertia vector. I could have done some math incorrectly, so if anything jumps out please tell me. 1. Quaternion->matrix * inertia = rotated inertia
[1 - (2Y  + 2Z)			2XY + 2ZW			2XZ - 2YW		]		[M 0 0]
[2XY - 2ZW			1 - (2X^2  + 2Z^2)		2YZ + 2XW		]	*	[0 N 0]
[2XZ + 2YW			2YZ - 2XW			1 - (2X^2  + 2Y^2)	]		[0 0 O]

	[M - M(2Y + 2Z)		2XYN + 2ZWN			2XZO - 2YWO		]
=	[2XYM - 2ZWM		N - N(2X^2 + 2Z^2)		2YZO + 2XWO		]
	[2XZM + 2YWM		2YZN - 2XWN			O - O(2X^2 + 2Y^2)	]

2. Rotated inertia * vector = inertia-scaled-vector
[M - M(2Y + 2Z)		2XYN + 2ZWN			2XZO - 2YWO		] * [A]		[AM - AM(2Y + 2Z) + 2BXYN + 2BZWN + 2CXZO - 2CYWO	]
[2XYM - 2ZWM		N - N(2X^2 + 2Z^2)		2YZO + 2XWO		] * [B] =	[2AXYM - 2AZWM + BN - BN(2X^2 + 2Z^2) + 2CYZO + 2CXWO	]
[2XZM + 2YWM		2YZN - 2XWN			O - O(2X^2 + 2Y^2)	] * [C]		[2AXZM + 2AYWM + 2BYZN - 2BXWN + CO - CO(2X^2 + 2Y^2)	]

If this is what I use, I figure I'll write an inline function to multiply a vector by the rotated inertia, given a quaternion and the original inertia.

Share this post


Link to post
Share on other sites
jyk    2094
Disclaimer: the following are just ideas and may or may not be correct.

First of all, you might consider changing your position on coding a matrix class. You can get by without it, but it would probably be useful to have. For example, every time you rotate a vector by a quaternion, you're essentially creating an intermediate matrix and multiplying it with the vector. Having a 3x3 matrix class means you only need to convert the quat to a matrix once, after which you can easily and cheaply rotate multiple vectors.

Anyway, regarding the tensor. The usual method is not so much to rotate the tensor into world space, but to perform a similarity transform, that is, rotate the vector into the local space of the object, apply the tensor in local space, and then rotate back into world space. Your tensor is presumably a scale matrix (single vector) due to the shapes you're using. After rotation the tensor will no longer be a diagonal matrix, so I'd think you'd want to avoid rotating it. Instead, just perform the similarity transform as described in the articles, as follows:

1. Rotate by the conjugate of the orientation quat to get to the object's local space
2. Apply the scaling 'manually' to the resulting vector
3. Rotate by the quat to get back to world space

I've never actually tried this so I can't guarantee it'll work, but the idea seems right. Again, though, matrices make this all a lot easier.

Share this post


Link to post
Share on other sites
Rendaw    150
Thanks for the quick reply.

Regarding your note about matricies, I rotated vectors by making a quaternion from the vector, and then performing a quaternion-quaternion multiplication. I don't exactly know if this is derived from matrix multiplication, but other than that I'm not explicitly converting from quaternion to matrix. I realize that there are many situations in which having a matrix class may help (such as various OpenGL operations), but unless forced to create one I'm going to try to stay away.

As for the inertia tensor, the only problem with transforming a vector to local space, scaling, and transforming back, is that there are many places I have to use the rotated inertia - impulse calculation, angular momentum->angular velocity, etc. If I were to do this, in each place I transform from world->local->world, I would have to perform two more quaternion multiplications. It might work (in terms of performance) in my current project, but it dosen't seem like the best long term goal.

Share this post


Link to post
Share on other sites
jyk    2094
Quote:
Original post by Rendaw
Thanks for the quick reply.

Regarding your note about matricies, I rotated vectors by making a quaternion from the vector, and then performing a quaternion-quaternion multiplication. I don't exactly know if this is derived from matrix multiplication, but other than that I'm not explicitly converting from quaternion to matrix. I realize that there are many situations in which having a matrix class may help (such as various OpenGL operations), but unless forced to create one I'm going to try to stay away.

As for the inertia tensor, the only problem with transforming a vector to local space, scaling, and transforming back, is that there are many places I have to use the rotated inertia - impulse calculation, angular momentum->angular velocity, etc. If I were to do this, in each place I transform from world->local->world, I would have to perform two more quaternion multiplications. It might work (in terms of performance) in my current project, but it dosen't seem like the best long term goal.
Well, I don't want to push the matrix thing if you're really trying to avoid it, but I will offer a couple more quick observations.

Re: quaternion-vector rotation. As you no doubt already know, the equation q*p*q', where ' is conjugate, rotates p by q, more or less. When you multiply this equation out, you get what is essentially a 3x3 matrix times vector multiplication. This is in fact one way to derive the corresponding rotation matrix for a quaternion. So in your quaternion-vector rotation code, you're almost certainly *implicitly* converting the quaternion to a matrix, even if you don't have a matrix class per se. The advantage of the matrix is that you do the conversion once (when your quaternion changes), and then can perform as many vector rotations as you want using a relatively inexpensive matrix-vector multiplication.

As for the second problem of multiple world->local->world transforms, matrices once again come to the rescue. I don't have the equation in front of me right now, but I believe the impulse calculation takes advantage of the similarity transform the same way the momentum->velocity equation does. With matrices, you compute this transform once, as R*Ibodyinverse*R^T. This need only be done when the body's orientation changes (usually once per physics update), and after that the world->local->scale->world transform is reduced to a single matrix-vector mult. It's not immediately clear to me how you'd accomplish the same thing with quaternions only.

So those are just some thoughts. Doing all this exclusively with quats seems like a bit of an uphill battle to me, but I might be overlooking something...

Share this post


Link to post
Share on other sites
Rendaw    150
No, you're probably right. So far, I haven't encountered anything other than this in which I'd rather use matricies than quaternions. Quaternions work well for rotating meshes, forces, various joints, and so on. Although, I guess that the mesh rotations might be faster with a matrix rotation as well.

Thanks again.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this