Gimbal Lock and Quaternions

Started by
22 comments, last by abolfoooud2 18 years, 7 months ago
Regards, i am trying to use Quaternions to rotate an objet around the global X axis then around the global Y axis. i am converting the Quaternion to a matrix form to multiply it with the current matrix (using OpenGL). so i will have something like the follwoing: // the hidden global matrix, not implemented by myself CurrentMatrix(); // Quaternion-to-Matrix Rotatation around X MyQuatRotate(X, angle); // Quaternion-to-Matrix Rotatation around Y MyQuatRotate(Y, angle); but when this code is applied, the first rotation is performed around the global X axis but the second one is excuted around the object's local Y axis. is this what is called a Gimbal Lock??? and how can i solve it???? thanx
Advertisement
I think its only gimbal lock if you rotate the Y by 90 degrees.
A simple search for 'gimbal lock' on [google] reveals all - Take a look here for a description of gimbal lock.
Its simple enough to solve, just don't rotate the XYZ components separately (This can't be done using euler angles and is why quaternions are so popular).
Presumably if you are trying to rotate and object, you know what angle to rotate to, so you can get the quaternion of that rotation and use that instead of computing the components separately.

Conceptualy, euler angles are easier to use, so let people suffer with gimbal lock to rotate an object to the correct angle but after that use quaternions to do all the work, since computers have no metal block dealing with them.

rotating the object in the same function around the two axes will not benifit my application since i need to have the functionality of allowing the user to rotate the object around either axes (X or Y) separately. so, making the one rotation with one function call will not make it worw as desired.

do u suggest something else? i thought of trying SLERP, but i think it wont do what i an looking for since it is for animation smoothness adn i am not seeking this.
gimble lock is really more of a problem with interpolation. if you're just using quaternions to represent rotations, and not using them to interpolate, then you got the concept wrong. For example if you're camara is interpolating x,y,z angles for it's movements, you get gimble lock if or if not using quaternions. what happens in when you're in a situation where your camera has an x,y,orz rotation that is close to 90degrees you get into a situation where small changes in x, y, z produce no noticible change in orientation. you camara get's stuck in a sense and there is no "small" rotation you can apply to get it unstuck. if you're just using quaternions to do rotations about the x, y, z axis this is mathematically equivilent to rotation using eular angles about the x, y, z axis. to see this simply convert the quaternion representing the rotation about the x axis into a matrix and you'll notice it's the same matrix you'd get using eular angles.

all that aside, the problem your having is this, it is NOT GIMBLE LOCK


suppose I have the matrix equation:
p = A*B*C*D*x

where A, B, C, D are matrix, and x is a vector.

say these matricies represent rotations.

there are two different ways to read what this is doing.
if I read right to left I have to think of the transformations being applied to the GLOBAL axis. if I read them right to left I have to think of the transformations being applied to the local axis, the reason you think the first rotation is being applied to the global x axis is because initially, the global x axis is the local x axis. let me try to think of a reasonable example

suppose I got a book that is initailly parallel to the x-y plane and I rotate it 90 degrees about the GLOBAL z-axis then 90 degrees about the GLOBAL x-axis. now we have a book that lies in the x-z plane. so suppose matrix A is a 90degree rotation about x and B is a 90 deg rotation about z then the equaiton we use to do this transformation is

p = A*B*x
note that if I read it right to left you get exactly what I described above.that is first we see B and see that its a 90 degreee rotation about the z axis, now what z axis?? The GLOBAL z. now we next read A and see that it's a 90 degree rotationo about the x axis, and since we're reading right to left it's the GLOBAL x axis.

so now lets read it from left to right, just to see the difference(this is the better way to read btw)

we first see A and we note that it's a rotation about x-axis, since we're reading left to right it's the LOCAL x axis. we then see B and we determin that A*B is taking the model and rotating it 90 deg about the LOCAL X-axis then rotation it 90 deg about the LOCAL z-axis. realize that this is two ways of thinking about the same thing, the end positoin of the model is the SAME it's all in how you think of it.

if you read left to right you have to think of the transformaitons as being applied to the local axis, if reading right to left you think of things being applied to global axis.

in openGl reading TOP to BOTTOM is like reading LEFT to RIGHT in the above equations. so when reading your code top to bottom you have to think of the transformations as being applied to the local axis. if you read bottom to top you can think of them as being applied to the global axis.

so in reading your code top to bottom I see
rotate model "angle" degrees about the local x-axis,
now rotate the model "angle" degrees about the local y axis

reading your code bottom to top I see
rotate the modeel "angle" degrees about the global y axis
then rotate the model "angle" degrees about the global x axis

it doesn't matter which one you do, the end orientation will be the same, I hope you see why it's rotating about the local axis now..

Tim
yes, gimbal lock is if you rotate components separately for 90 degrees. if you do so, you basicly overlapp on axis this the other. to solve you problem, you need to have to scene nodes in your scene graph, one for x rotation and one for y rotation, and most important, the y node as a child for x node, and the object you want to rotate as child of the y node. something like that is when you make rotation within Ogre3d engine. hope it helps
what the heck are you talking about? this is a simple order of operations problem..
thank u very much timw....
u really explained something i never noticed. u r completely right about that misconception i had about the local and global axses i was doing the rotation around. now, u made me really feel bad though :( i though that i made some progress in making one axis rotation work fine :p
any ways, do u recommend any other solution to achieve a full global-realted rotation instead of a local one? like the object rotation that is in any 3D modeling application like 3D max when u rotate the object to view it from all directions??
Quote:this is a simple order of operations problem..
Are you sure about that? I was under the impression that he wants to be able to rotate his object about any global axis, regardless of the object's current orientation. I'm not clear on how you would do this with Euler angles, regardless of order of operations.

@The OP: I proposed a solution to your problem in your other thread, here. Is there some reason that won't work for you? Or is it simply an implementation problem?

This is all assuming that I understand what the OP wants to do. But I could be misinterpreting...

well, u r not misinterpretting at all jyk. my problem is exactly what u realise: rotating my object around two arbitrary global axes sequencially, not simultaneously.

after ur last proposal in my previous thread, i took off surfing for a way to get the current matrix in OpenGL to be able to extract the current view of it to multiply it with a proper rot matrix frame by frame. but i couldnt find any.
i encountered something that cought my attention which was the SLERP thingy. i thought it could solve my prob, but then i found out that it is too much far from what i am trying to do. and i had the misconception of whether i am facing a Gimbal Lock or not !!!

however, timw's point is 100% accurate in my case. if i read the matrices from left to right i get different result for the global axis around which the rotation takes place than when reading from right to left.

what i am trying to chieve is exactly a viewing tool just like that in any 3D modeling app, Maya, 3D Max, 3D Exploration... when u move an object in the -x then +y directions, when the orientation of the object is lets say towards the screen -z, the object rotates to the left-upper side. then if i rotate the object in the -x direction, it should flip over around the global x, not rotate around its x as it is happening to me.

all this hassle is blending me in a blender that i cant stop untill now.
can any body unplug it :p

Hey

Quote:this is a simple order of operations problem..

Order of operation is an issue whether you use matrices or quaternions.

Quote:
Are you sure about that? I was under the impression that he wants to be able to rotate his object about any global axis, regardless of the object's current orientation. I'm not clear on how you would do this with Euler angles, regardless of order of operations.

I don't see the problem here.
If we are talking about global main axes (XYZ) you simply construct the rotation matrix and multiply it with the current matrix.
If its ANY global axes, well, construct quaternion (axis angle) convert it to matrix and multiply it with the current matrix.
The fact that you may end up with gimbal lock is totally different issue.

Quote:
@The OP: I proposed a solution to your problem in your other thread, here. Is there some reason that won't work for you? Or is it simply an implementation problem?

This is all assuming that I understand what the OP wants to do. But I could be misinterpreting...

Ok jyk, never mind what I just said :) you've already talked about it.

People are generally confused about the gimbal lock and the ability of quaternions to avoid it.
Just because something looks like Gimbal lock it does not necessarily mean it is one.
If you start mixing global axes and local axes, quaternion math and matrix math
you can end up with more problems than just gimbal lock.

Quaternion is NOT a gimbal lock filter.
Lets say you have matrix M that "suffers" from gimbal lock. Converting M to quaternion DOES NOT remove the gimbal lock. You just have a different representations of the same problem.

Quote:i am trying to use Quaternions to rotate an object around the global X axis then around the global Y axis. i am converting the Quaternion to a matrix form to multiply it with the current matrix


This is the classic problem.
You convert quaternion to matrix and then you multiply it with another matrix.
This matrix multiplication can give you gimbal lock.
You've broken the "quaternion flow" and introduced flawed matrix operation.

I'll tell you what I usually do:

If I know that I may end up with gimbal, I create the Object and
unit quaternion at the same time. This unit quaternion is my initial
orientation representation. From this point I only do quaternion math.
At no point do I extract matrix just to multiply it with another one.
The only reason to extract matrix is to use it on your Object.
Once this matrix is applied it's discarded, and I am back to
quaternions where I left off.

1. Create object
2. Create unit quaternion Q
3. Create new qauternins Q1, Q2, Q3... representing desired rotations
4. Multiply two qauternions Q=Q*Q1*Q2*Q3...
6. If needed, extract matrix M from Q and use it on your Object
5. Go back to step 3

V

This topic is closed to new replies.

Advertisement