Quaternions step by step

Started by
17 comments, last by Dmytry 17 years, 6 months ago
I hate to disappoint you, but typically a quaternion is used only for storage and intermediate computations and is converted to a rotation matrix when needed for a transformation. But if you want to use a quaternion, then (as jyk wrote) everything is pretty much the same except that you use a quaternion in place of a rotation matrix.

To answer your specific questions (note that many of your questions don't make sense if you have already done this using matrices):

1. ok
2. Vold is a position. Quaternions represent orientations, not positions. The formula computes a rotated position.
3. ok
4. Yes, but the question is still, "what is Vold"? What are you rotating?
5. No, see my comments in #2.
6. No, see my comments in #2. To accumulate rotations, you simply multiply the current orientation by this frame's rotation. Qnew = Qold * Qframe.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Advertisement

so thanks a lot.

i was confused with all the stuff before your posts. now i know that Vold is the position vector. So when i take the position of the body (the position of his local center point) and construct a quaternion for example with
FromAxesAndAngles i can apply them in the formula to get Vnew. Am i right?

What information can I extract from Vnew. Can I transform Vnew direct in rotation matrix and apply the matrix on the body (using for example something like
dBodySetRotation(newRotMatrix))?
hi once again

i've tried all the things that u said and can say...now at least is the body rotating in my scene . Ok, not the way I want to be. Like u said, i tried to store the current rotation of the body in quaternion (camQuat). by every key-input i compute the new rotation using Euler Angles and store the result in a Quaternion (resultQuat).

After that i multiply the quaternions:

camQuat = resultQuat * camQuat;(1)

and apply the camQuat to the body. When I pitch and after that yaw, the body yaws around the local z Axis(x,y,z-up). I want the body to yaw always around the world z Axis. So i changed the order in (1) to
camQuat = camQuat * resultQuat ;(2)
and it works for yaw and pitch perfect. The big problem is the roll. When I roll after that is everything wrong. (in both cases)

What is the best way to become the body yawing always around the global z-axis independent from the pitch and the roll. By pitch and roll the body have to rotate around local axes x(for pitch) and y(for roll).

Any ideas?
Quote:Original post by nebemore
hi once again

i've tried all the things that u said and can say...now at least is the body rotating in my scene . Ok, not the way I want to be. Like u said, i tried to store the current rotation of the body in quaternion (camQuat). by every key-input i compute the new rotation using Euler Angles and store the result in a Quaternion (resultQuat).

After that i multiply the quaternions:

camQuat = resultQuat * camQuat;(1)

and apply the camQuat to the body. When I pitch and after that yaw, the body yaws around the local z Axis(x,y,z-up). I want the body to yaw always around the world z Axis. So i changed the order in (1) to
camQuat = camQuat * resultQuat ;(2)
and it works for yaw and pitch perfect. The big problem is the roll. When I roll after that is everything wrong. (in both cases)

What is the best way to become the body yawing always around the global z-axis independent from the pitch and the roll. By pitch and roll the body have to rotate around local axes x(for pitch) and y(for roll).

Any ideas?

if you want yaw to be global and roll and pitch local, make separate rotation quaternion for yaw, and multiply it on the left, and multiply the pitch and roll on the right.
I.e. like
camQuat=yaw * camQuat * pitchAndRoll.

anyway, if you are doing this kind of movement and want it working precisely as with euler angles, there's not much purprose in using quaternions.
hmm, what is the better approach in this case?

Dmytry: i've tried what u said, and yaw is working fine (rotating around global z), roll is working also fine(around local y), only pitch is going wrong(for example when i first roll and after that pitch, the pitch is no more correct.) I have tried with Euler Angles and with FromAxisAndAngle - same result.

here pseudo code: (in every frame)

//yawQuat,pitchQuat,rollQuat - Quaternions;
//angleY/P/R = angle if key pressed, else 0

QFromAxisAndAngle (yawQuat, 0, 0, 1, angleYaw);
QFromAxisAndAngle (pitchQuat, 1, 0, 0, anglePitch);
QFromAxisAndAngle (rollQuat, 0, 1, 0, angleRoll);

Quat temp = rollQuat * pitchQuat;
//modelQuat holds the current rotation
modelQuat = yawQuat * modelQuat;
modelQuat = modelQuat * temp;

//sets Quat to body
BodySetQuaternion (body, modelQuat);

how can i fix it?

Well, firstly: This really is no issue of "correct" and "incorrect", there's issue of knowing what kind of control specifically you want and implementing this kind of control.
It looks like what you want is not really pitch, yaw, and roll (otherwise you'd simply need them all to be global or local and no problem in first place).

My guess is that you want to emulate addition of euler angles with quaterions, so that "yaw" turn around global vertical axis, "pitch" turns around the the local side (x) axis projected onto ground (xy) plane, and "roll" turn around local forward axis (y) . You will get gimbal lock with quaternions there as well as with euler angles, as the gimbal lock is a problem of this concept of motion and not really of how orientation is storen.

The pseudocode for guess:

// note, gonna have gimbal lock like euler.
vector p_axis=TransformFromCameraSpaceToGlobalSpace(Vector(1,0,0));
p_axis-=DotProduct(axis,Vector(0,0,1))*axis; // note: it's not unit length anymore. QFromAxisAndAngle need to handle it gracefully

QFromAxisAndAngle (yawQuat, 0, 0, 1, angleYaw);
QFromAxisAndAngle (pitchQuat, p_axis, anglePitch);// note: the pitch is in global space because we transformed it above
QFromAxisAndAngle (rollQuat, 0, 1, 0, angleRoll);

modelQuat = yawQuat * modelQuat * pitchQuat * rollQuat;

(I'm still not certain it is really the kind of control you want)
hmm, the forum was down...

Dmytry: thanks for your reply. my main goal is to implement a camera that yaw/pitch/roll around local axes (my first post) and the rotations have to be correct (no gimbal lock).

That with the yawing around global axis was just...curiosity. i've tried but don't like the results.

to the main problem: as i'm understanding to avoid gimlble lock i have to compute every frame the new rotation quaternion(or matrix) and after that multiply the current quaternion with the new one (in this order). and for the computation of the new one is equal using QfromEulerAngles or QfromAxisAndAnle.

feel free to correct me i'm talking nonsense

cheers
if you want to do pitch/yaw/roll around local axises, just multiply them with camera's rotation quaternion from the right. Then you get the camera as for flight or space simulator.

Obviously since you have questions it is not what you want right? I think something around 90% of problems with rotations (or just problems) in this forum is just problem with poster knowing/understanding what he want, in terms of rotations. Try taking some cube, write X,Y,Z on three sides (the vectors is then pointing to the center of side). Also define global directions in the room (like x to window, y to right, z to up), then play around with this cube. Rotation around local axis, is rotation about cube's axis. Rotation around global is around room's axises. Then you can figure what rotations do you want. It's interesting that most people (except to who's job it is relatd) don't quite understand the rotations in 3D space in which they live, so it's not just you.

As for gimbal lock, there seems to be lot of confusion. The rotations needs to be clarified first, then you can begin to understand what is gimbal lock, why and when it happens. "euler angles = gimbal lock, quaternions = no gimbal lock" is as informative as not knowing about gimbal lock at all. Gimbal lock is really a problem with controls behavior when you look up or down. If you have controls exactly as for euler angles cam, it will lock just as well as straightforward euler angles based implementation.

edit: btw, alternatively, you can specify which known game has camera like one you want. If it's quake/halflife/other FPS, what's the problem with euler angles again? the camera controls inherently have to stop when you look straight up or down.

[Edited by - Dmytry on October 9, 2006 5:12:43 PM]

This topic is closed to new replies.

Advertisement