PDA

View Full Version : Quaternions - ARG!



PhireBat
04-05-2001, 10:57 AM
i heard you can use quaternions to avoid gimbal lock, so i got myself some quaternion functions and tried them out.
what i did was used a function to convert euler angles (roll pitch yaw) and put them in a quaternion q (w [xyz])
then i did:
glRotatef(q.w, q.x, q.y, q.z);
it hardly moves at all! about 2 degrees either way =( plz help me out

rts
04-05-2001, 11:34 AM
q.w q.x q.y and q.z are not what you think they are.

Here is what I've done:




GLfloat m[16];
QUAT q;
/* ... */
/* Compute q */
/* ... */
/* Convert to a rotation matrix */
QUAT_ToMatrix(&q, m);
/* ... */
/* Set up your projections, etc */
/* ... */
/* Set orientation */
glMultMatrixf(m);
/* Carry on... */

PhireBat
04-05-2001, 12:29 PM
now i seem to have no yaw at all =(
could anybody plz send me a basic example in code of how a flightsim is done?

Korval
04-05-2001, 12:35 PM
Several questions:

1) How did you compute your Quaternions from your Euler angles? I assume you didn't just stick the angles in the vector part of the Quaternion.

2) How did you do the Quaternion multiplication?

Nutty
04-05-2001, 01:53 PM
i heard you can use quaternions to avoid gimbal lock


I read somewhere that OpenGL's own matrix code automatically prevented gimbal lock.

rts
04-05-2001, 02:23 PM
Originally posted by PhireBat:
could anybody plz send me a basic example in code of how a flightsim is done?

Well, it isn't very basic, but Flight Gear (http://www.flightgear.org) is a Free-as-in-speech flight simulator. Check out their source if you're so inclined.



[This message has been edited by rts (edited 04-05-2001).]

Korval
04-05-2001, 04:58 PM
No, OpenGL has no code to prevent Gimbal Lock.

Elixer
04-05-2001, 05:34 PM
I have to agree, that is incorrect Nutty, openGL has no support for that.

You can use matrices to avoid gimbal lock, so you do not need quats though. It all depends on what you do.

Michael Steinberg
04-05-2001, 07:18 PM
What the hell is a "Gimbal Lock" ???

;-) Excuse my lack of knowledge... ;-)

AndersO
04-06-2001, 02:23 AM
Not entirely sure myself, but I think it means that, for example:
You rotate an object around z axis (roll) 90 degees and then try to rotate the object around its y axis (yaw) 90 degrees.

You then would expect the object to point either up or down, but infact the yaw didn't occur around its local y axis, but in world y axis.

So the object turns either left or right.

Or something like that, when I stumbled on this problem I was told it was called gimbal lock.

I solved it by using my own rotate functions, building a matrix and send it to OpenGL. True, the same problem can occur in my own functions but I only rotate a small step at a time around any axis. Wich helps.

Lately I have thought of just separate each glrotatef call with a pushmatrix and thought that might produce the same results as my own functions but haven't tried that yet.

But I digress, I know nothing about quaternions..

Cheers

Nutty
04-06-2001, 03:59 AM
I dont recall where I read it, but thats what it said.

Nutty

Nocturnal
04-06-2001, 07:35 AM
You do not need to suffer through gimbal lock in OpenGL if you use glRotate. You get into trouble when you split glRotate into 3 calls: once for each axis of rotation. glRotate can rotate about an arbitrary axis, like a quaternion. It is straight forward to use quaternions with glRotate:

factor = 1.0 / sqrt(1-(q.w*q.w));
glRotate(acos(q.w) * 2 * pi,
q.x * factor,
q.y * factor,
q.z * factor);

See: http://skal.planet-d.net/demo/matrixfaq.htm

[This message has been edited by Nocturnal (edited 04-06-2001).]

EricK
04-06-2001, 08:57 AM
Originally posted by AndersO:
Not entirely sure myself, but I think it means that, for example:
You rotate an object around z axis (roll) 90 degees and then try to rotate the object around its y axis (yaw) 90 degrees.

You then would expect the object to point either up or down, but infact the yaw didn't occur around its local y axis, but in world y axis.

So the object turns either left or right.

Or something like that, when I stumbled on this problem I was told it was called gimbal lock.


That is definitely not gimbal lock. What you described is an attribute of glRotate. The input to glRotatef is 4 floats. The first is the angle of rotation and the last three are the vector about which the scene is rotated. This vector is defined in the world frame. It is not the yaw.

Eric

EricK
04-06-2001, 09:45 AM
Originally posted by EricK:
That is definitely not gimbal lock. What you described is an attribute of glRotate. The input to glRotatef is 4 floats. The first is the angle of rotation and the last three are the vector about which the scene is rotated. This vector is defined in the world frame. It is not the yaw.

Eric

errr, of course I checked this after I wrote it, not before! (I think I confused myself with a glLoadIdentity awhile ago) The rotation vector is defined in the local frame, the rotation matrices are multiplied as is stated in the faq. If you use the z-y-x (or x-y-z) Euler sequence then gimbal lock would have occured when the rotation about the y axis (second) was 90 degrees. Then the z and x (first and third) rotations would have been about the same axis. It is always the second rotation which gives you gimbal lock and it occurs when the rotation is 0 or 90 depending upon the sequence (it is 0 for an x-y-x sequence, for example).

PhireBat
04-06-2001, 09:48 AM
ok, heres the code for converting euler angels to quaternions:

GLfloat cr, cp, cy, sr, sp, sy, cpcy, spsy;

cr = cos(roll/2);
cp = cos(pitch/2);
cy = cos(yaw/2);

sr = sin(roll/2);
sp = sin(pitch/2);
sy = sin(yaw/2);

cpcy = cp * cy;
spsy = sp * sy;

quat->w = cr * cpcy + sr * spsy;
quat->x = sr * cpcy - cr * spsy;
quat->y = cr * sp * cy + sr * cp * sy;
quat->z = cr * cp * sy - sr * sp * cy;

how do i use the resulting quaternion to set the orientation of the camera?

EricK
04-06-2001, 10:50 AM
see Nocturnal's post

Korval
04-06-2001, 10:52 AM
Where did you get that code from? As far as I understand it (which isn't very far, I might add), that is incorrect.

What you need to do is turn each individual Euler Angle/axis rotation into quaternions and perform quaternion multiplication on them to get the correct quaternion. Then, use that quaternion to compute the rotation matrix.

PhireBat
04-06-2001, 10:57 AM
I got this stuff from the "Power of Quaternions" article on gamedev.net
what is the problem and can it be fixed/

EricK
04-06-2001, 12:18 PM
Originally posted by Korval:
Where did you get that code from? As far as I understand it (which isn't very far, I might add), that is incorrect.

What you need to do is turn each individual Euler Angle/axis rotation into quaternions and perform quaternion multiplication on them to get the correct quaternion. Then, use that quaternion to compute the rotation matrix.

???
It is not hard to derive your own conversion equations. You can write down (look up in a book?) the rotation matrix in terms of Euler angles. Then do the same for quaternions. Now you have two matrices that are equal. Hence nine equations which map the Euler angles into quaternions. Start simplifying.
You can also do this with a rotation angle/vector representation (the kind that glRotate expects). I bet in an hour you can derive the equations (convert quat to EA, EA to quat, quat to angle/vector, ...) that listed on the matrixfaq page that Nocturnal mentioned.