• 10
• 9
• 13
• 10
• 18

# [XNA] Orientation & Rotation using matrices and quaternion

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

## Recommended Posts

Hi,

I am writing an Asteroid clone and i got few problems and questions. So i though i would ask here for advices and comments.

Firstly, even if im planning on using quaternion to rotate my objets, im storing their orientation as a matrix. Im doing so since it seems easier to do lots of stuff, like transforming coordinates from world to local or simply getting a forward vector. Any thoughts about this, is this practice common or should i store the orientation as a quaternion?

Secondly, even if all seems to work as they should, i've got some kind of error in my rotation code. Im using this code snippet to turn the ship.
// Orientation is the Ship's Orientation store as a MatrixQuaternion q1 = Quaternion.CreateFromRotationMatrix(Orientation);Quaternion rot = Quaternion.CreateFromAxisAngle(Vector3.Up, 0.2f);Quaternion final = q1 * rot;Orientation = Matrix.CreateFromQuaternion(final);

Question: result seems the same if im swapping quaternion multiplication order (seems odd to me). Is this a normal behavior? From what ive red, no!
// in the above code, either of theses line are giving me the same result.// as if: q1 * rot = rot * q1final = q1 * rot;final2 = rot * q1;

Problem: I got a bug and it's really hard to reproduce it. Very rarely as im moving around the screen and turning the ship around. The ship go out of control and seems to zoom in/out or being tranlated up/down (instead of turning normally). I cant track the problem down, but im sure its has to do with the way im using thoses quaternion to rotate my objects.

Any comments or ideas are welcome...
Thanks you!

##### Share on other sites
Successive rotations around the same axis commute; this is why changing the multiplication order isn't having any noticeable effect.

Regarding the quaternions, my advice is to drop them completely unless you have a clear, definite understanding of what their use will gain you in the given context. In other words, if you're not sure why you're using them, don't use them (just stick with matrices).

As for your bug, I don't know, but one thing I noticed is that you don't appear to be normalizing your quaternion after applying the relative rotation. Whether you're using quaternions or matrices, you should normalize the orientation after applying a relative rotation in order to prevent numerical drift.

Also, if your object will really only ever rotate about a single axis, you could simply track the angle of rotation about that axis and build the orientation from scratch each update. This would solve any potential numerical issues that might come up. (Even with normalization, successive relative rotations could theoretically cause the orientation to drift out of alignment with the up vector. That's probably unlikely to happen in this particular scenario, but building the orientation from scratch will eliminate the possibility entirely.)

##### Share on other sites
Thanks for answering me. Im using quaternion since i want to turn the tradional asteroid game into a "3d" version (meaning you can rotate in any direction and chase asteroids in a 3d space rather then a 2d world). Im using them to avoid the famous gimbal lock problem. Can i achieve the same with matrices only?

About your comment on normalization, do you mean something like this? And can you explain what you mean about normalizing a matrice? i dont see how i can do this (i cant find nothing in xna documentation).
Quaternion ori = Quaternion.CreateFromRotationMatrix(Orientation);Quaternion rot = Quaternion.CreateFromAxisAngle(Vector3.Up, 0.2f);// i'm assuming this is the right order (or is it ori * rot)Quaternion final = rot * ori;final.Normalize();Orientation = Matrix.CreateFromQuaternion(final);

You are also talking about the multiplication order. From what i understand this should be the right way to do it? am i right? (Transformations are applied from right to left).
Quaternion ori = Quaternion.CreateFromRotationMatrix(Orientation);Quaternion rotPitch = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), GetPitchInput());Quaternion rotRoll = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), GetRollInput());Quaternion rotYaw = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), GetYawInput());// Is this correct?// Should i normalize before, between each transforms or only afterQuaternion final = rotPitch * rotRoll * rotYaw * ori;final.Normalize();Orientation = Matrix.CreateFromQuaternion(final);

Would an implementation like this suffer from numerical error?

##### Share on other sites
Quote:
 Im using quaternion since i want to turn the tradional asteroid game into a "3d" version (meaning you can rotate in any direction and chase asteroids in a 3d space rather then a 2d world).
My earlier comments regarding quaternions still apply - whether it's 2-d or 3-d doesn't matter.
Quote:
 Im using them to avoid the famous gimbal lock problem. Can i achieve the same with matrices only?
Yup. Whether or not you use quaternions has nothing to do with whether your rotations will be susceptible to gimbal lock.
Quote:
Yes, that looks right. (Note that all that converting back and forth between quaternions and matrices is probably unnecessary. Either just use matrices, or use quaternions consistently throughout and only convert to matrix form as needed.)
Quote:
 And can you explain what you mean about normalizing a matrice?
With matrices the process is called 'orthogonalization'.

Note earlier that I suggested not using quaternions unless you can articulate how using them would be advantageous. Here's one way using them can be advantageous: normalizing a rotation in quaternion form is easier than doing so in matrix form. (I don't know if XNA has a matrix orthogonalization function already - if it does, then it doesn't really matter which you use, since it's just a matter of calling the appropriate function.)
Quote:
 // Is this correct?// Should i normalize before, between each transforms or only afterQuaternion final = rotPitch * rotRoll * rotYaw * ori;final.Normalize();Orientation = Matrix.CreateFromQuaternion(final);Would an implementation like this suffer from numerical error?
Assuming I'm understanding the context of your code correctly, that should be fine; normalizing the quaternion before re-building the orientation matrix will correct for any accumulated numerical error.

As for the order, which order is correct depends on the desired effect and how quaternion multiplication is defined. (I can't remember if XNA uses standard or 'reverse' quaternion multiplication order - I think it's standard, but I'm not sure.)

##### Share on other sites
Thanks for quick response, my code looks like it performing correctly: no more weird zooming in and out even after playing a few levels.

About making normalizing matrices in XNA, ive not found anything in the documentation. However, this shouldnt be too hard, its just a bit of cross-product and vectorial maths to make sure the vector are orthogonal to each other.

About quaternion, after re-reading a few references i had. Would their only usefull quality is their ability to be easily interpolated? Or can you tell me or descripe me where quaternion are best used.

Thanks again!

##### Share on other sites
Quote:
 Or can you tell me or descripe me where quaternion are best used.
There's really nothing that quaternions can do that rotation matrices can't. However, here are some things that are commonly cited as advantages with respect to quaternions:

1. Lower storage requirements than matrices.
2. More efficient concatenation.
3. More efficient normalization of orientations.
4. More efficient and (arguably) more elegant NLERP, SLERP, SQUAD, etc.
5. There's a couple of nice quaternion-specific algorithms for rotating over the shortest arc from one vector to another.
6. Numerical error can accumulate more slowly (theoretically, at least). If you're re-normalizing every update anyway though, this doesn't really matter.
7. Probably some other things I'm forgetting.