Sign in to follow this  

Three-axes Rotation with Quaternions

This topic is 4592 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

Hi! I'm sorry if this has been asked before. I've been searching for an answer for awhile, so if there is an answer (to my rather stupid question) please point me to it. Now. I've been hacking some quaternions together, and after a bit of trying I am now able to fly through space, using my joystick. It works like a charm, but since I don't quite understand quaternions (yet) I thought it might be a good idea to ask if I do it right. The way I do it now is, I have my pitch, yaw and roll increments stored every frame in delta_pitch, delta_yaw, and delta_roll. Rotation velocity per axis is at most 90deg/s so with around 430 fps the deltas are very small. I build my three quaternions q_delta_pitch, q_delta_yaw, and q_delta_roll like this:
q_delta_pitch.fromAxisAngle( delta_pitch, 1.0, 0.0, 0.0 );
q_delta_roll.fromAxisAngle( delta_roll, 0.0, 1.0, 0.0 );
q_delta_yaw.fromAxisAngle( delta_yaw, 0.0, 0.0, 1.0 );

Note that I'm using OpenGL with the positive z-axis as up-vector. I then apply these deltas to my rotation:
q_rotation = q_rotation * q_delta_pitch * q_delta_roll * q_delta_yaw;

This rotation is then applied to my camera. This works perfectly. I pitch when I want to pitch, I roll when I want to roll, and I yaw when I want to yaw. However, as I said earlier, my deltas are really small, so I can't really tell whether this is the right way to do it, but I believe it is not. Another way to do it would be to store the angles, and increment (or decrement) them every frame, and then build the rotation by first rotating the (identity) quaternion around the x-axis, then around the (local) y-axis, and then around the (local) z-axis. What is the best way to do it? I know I shouldn't rely on my high frame rate. But even after hours and hours of trying different combinations, I still need enlightment. ;-) Hope you understand my problem! Thanks in advance... Cheers, Drag0n

Share this post


Link to post
Share on other sites
I think that for greater accuracy and consistency at lower frame rates, you'll want to rotate around your object's local axes rather than the world axes (as you suggested in your post). Here is an article that discusses this approach, but with vectors rather than quaternions. In any case it should be a fairly easy adjustment to make to you code.

(This is assuming I read your code correctly...)

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
I think that for greater accuracy and consistency at lower frame rates, you'll want to rotate around your object's local axes rather than the world axes (as you suggested in your post).

Think the multiplication order of the quaternions results in exactly that, local-based rotations instead of world based.. but then i always get this stuff wrong >>;;

Share this post


Link to post
Share on other sites
Thanks alot so far guys.

So, should I stick to my delta-value based rotations, or is there some way of using my pitch, yaw, and roll angles to create a rotation? Using them as Euler angles doesn't really work...

EDIT: I don't have DirectX available (Linux), so can't test this myself. But how does D3DXQuaternionRotationYawPitchRoll() do it? ;-)

Cheers,
Drag0n

Share this post


Link to post
Share on other sites
Quote:
I don't have DirectX available (Linux), so can't test this myself. But how does D3DXQuaternionRotationYawPitchRoll() do it? ;-)
I don't know D3D, but my guess is that this function create a matrix from scratch as three successive rotations about the world axes. I could be wrong about that though.

In any case I would stick with relative, incremental rotation rather than trying to maintain a set of Euler angles. Rotate the quaternion successively about its local axes by your delta values. You'll want to renormalize the quaternion occasionally - it's cheap so it's reasonable to do it every update.

Share this post


Link to post
Share on other sites
Quote:
Original post by Drag0n
So, should I stick to my delta-value based rotations, or is there some way of using my pitch, yaw, and roll angles to create a rotation? Using them as Euler angles doesn't really work...

You /could/ keep track on cumulative Euler angles 'built' from the delta changes and then generate transformation matrix from them on each frame, but given this will eventually lead to the gimbal lock while offering little in return, it's perhaps better to stick to your current way (unless someone can suggest a better alternative ^^;

Share this post


Link to post
Share on other sites
Once again, thanks for your replies.

I decided to stick to my incremental method now. I switched back and forth between applying my delta values to local and global axes, but that didn't make any difference. It might have been a difference if I turned down the frame rate even more, but I guess anything under 10 fps is not what I would call playable, and at 10 fps I didn't notice anything. So, it seems to work.

As for normalization, my quaternion implementation "keeps itself normalized". Meaning, everytime an operation is performed that would denormalize the quaternion significantly, it calls normalize(). I've yet to find out (or derive) which operations these are exactly! Normalizing it once in awhile even though it (in theory) wouldn't be denormalized is probably also a good idea though. ;)

What I'm trying to do now is to draw a HUD, those elevation lines seen in fighter jets. I might come back and ask pretty soon... :)

Thanks again,
Dave

Share this post


Link to post
Share on other sites

This topic is 4592 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.

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