• Advertisement
Sign in to follow this  

What is the Quaternion equivalent for multiplying two 3x3 rotation matrices together?

This topic is 589 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Let's say you have a 3x3 matrix that stores an object's current rotation. As we know, by multiplying it with a new 3x3 rotation matrix, we will get a brand new rotation matrix.

 

newMat3x3 = Mat3x3A * Mat3x3B.

 

rwYwFdu.gif

 

Now, I have came across an issue where I see Mat3x3 rotation matrix being multiplied together to form the spinning cube, shown above. But the device that I'm using has limited memory, prompting me to figure out (and struggling along the way) to find an alternative to multiplying rotation matrices using quaternions (since it saves memory). In other words, I would like to replace rotation matrices with quaternions, but I don't know what is the quaternion equivalent to 2 rotation matrices multiplied together.

 

What is the quaternion equivalent to Mat3x3 * Mat3x3, or rotation matrix multiplications?

 

PS: I mashed 2 copies of the same cube together, so it is directly overlapping each other. One of the cubes is not spinning, because that cube is used for implementing the quaternion alternative method, but the method is not complete, so the orientation is set to its quaternion identity. So, no, it's not a graphical glitch, but an intentional test.

Share this post


Link to post
Share on other sites
Advertisement

The equivalent of matrix multiplication when using quaternions is... quaternion multiplication! (Surprise!)

 

So, this is correct?

// Generate new local_rotation, matrix-wise
// local_rotation = rotation matrix representing the current orientation
// new_rotation = rotation matrix representing the difference. (Rotation difference from new_rotation to local_rotation).
// total = rotation matrix representing (the final new orientation)
total = local_rotation * new_rotation

// Generate new local_rotation, quaternion-wise
// local_rotation = quaternion representing the current orientiation.
// total = quaternion representing (the local_rotation + the difference from the old orientation to the the final new orientation.)
total = local_rotation * total
Edited by tom_mai78101

Share this post


Link to post
Share on other sites
The result of composing two rotations depends on the order in which they are applied, so you may have to be a bit careful with the order of operands. In particular, it could be the case that your first operation should be `total = local_rotation * new_rotation', but it's hard to know without being familiar with the exact conventions you are using.

Share this post


Link to post
Share on other sites

The result of composing two rotations depends on the order in which they are applied, so you may have to be a bit careful with the order of operands. In particular, it could be the case that your first operation should be `total = local_rotation * new_rotation', but it's hard to know without being familiar with the exact conventions you are using.

 

The order I'm using is the order going from the left to the right. Same with the example I used in the GIF at the very top. I thought I was consistent enough and therefore there's no need to explain or define the multiplication order for both the Mat3x3 and the quaternions. Sorry.

 

As for the code snippet I mentioned, I was referring to your quote saying:

 

 

The equivalent of matrix multiplication when using quaternions is... quaternion multiplication! (Surprise!)

 

To me, it sounds like you were referring that, assuming the order of operations is exactly the same (going from left to right, and the placement is

 

result = old * new

 

The pattern of the following operation:

 

Mat3x3 result = Mat3x3 old * Mat3x3 new, where operator* denotes the multiplication, and Mat3x3 is the type.

 

Is exactly the same, literally and logically, as the following operation (just the pattern):

 

Quaternion result = Quaternion old * Quaternion new, where operator* denotes the multiplication, and Quaternion is the type.

 

I would like to seek clarification on this. Thanks again.

Edited by tom_mai78101

Share this post


Link to post
Share on other sites
You can use a 3x3 matrix as a rotation either by computing (row * matrix) or (matrix * column), and the order in which you have to multiply two matrices changes depending on what convention you are using. Similarly, you can apply a rotation expressed as a quaternion by computing either (q * v * conj(q)) or (conj(q) * v * q), and the order changes.

So in your conversion from matrices to quaternions, you may have to change the order. I am not going to check the correct order for you; I just wanted to warn you about this potential issue.

Share this post


Link to post
Share on other sites
Ah, it seems I was missing a conjugate to achieve rotation multiplication with quaternions.

No wonder I was confused about this. I will heed your warning.

Is there anything else I am missing in regards to quaternion alternatives to rotation matrix multiplications?

Share this post


Link to post
Share on other sites

I believe the order of quaternion multiplication is opposite the order of matrix multiplication. If the order is one way, it will occur on the global axis and if you do it the other way it will occur on the local axis. But with quaternions, I believe it's backwards from the way it is for matrices. I remember noting that at one point when working with quaternions.

 

Functionally, quaternions are almost the same thing as 3by3 matrices. One of the advantages of matrices is that they can be 4by4 and thus can store more information. And then every shader I've seen so far wants matrices, not quaternions, although I'm wondering why you couldn't have a shader that expects quaternions instead of matrices. You would have to submit the position separately, and I don't believe in using scale (scale the model right before you export it). And at some point, your transforming a vertex which is basically a 4by1 matrix. So maybe that's why.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement