# Three-axes Rotation with Quaternions

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

## 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 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 on other sites
Quote:
 Original post by jykI 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 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 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 on other sites
Quote:
 Original post by Drag0nSo, 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 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

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 9
• 9
• 9
• 14
• 12
• ### Forum Statistics

• Total Topics
633298
• Total Posts
3011249
• ### Who's Online (See full list)

There are no registered users currently online

×