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

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.

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.

Powered by vBulletin® Version 4.2.2 Copyright © 2014 vBulletin Solutions, Inc. All rights reserved.