PDA

cytricks
02-24-2011, 06:30 PM
I am working on a small program that moves a ball on a surface. It is very simple. I ran into a gimbal lock and dont know how to deal with it.

I found some code a person used for a quaternions but it still has the same problem. Can someone tell me what i am doing wrong. if you can please can someone show me an example of how to properly implement a quaternion

Alfonse Reinheart
02-24-2011, 07:35 PM

cytricks
02-25-2011, 09:22 AM
I read the link and it was very useful but i am still having the same problem. the code i am using for my quats are

float QuatX = 0, QuatY = 0, QuatZ = 0, QuatW = 1;

void multQuat(float x, float y, float z, float w)
{
float W = QuatW * w - QuatX * x - QuatY * y - QuatZ * z;
float X = QuatX * w + QuatW * x + QuatZ * y - QuatY * z;
float Y = QuatY * w - QuatZ * x + QuatW * y + QuatX * z;
float Z = QuatZ * w + QuatY * x - QuatX * y + QuatW * z;

QuatW = W; QuatX = X; QuatY = Y; QuatZ = Z;
}

void normalizeQuat()
{
float len = QuatX*QuatX + QuatY*QuatY + QuatZ*QuatZ + QuatW*QuatW;
if (len != 1.0) {
len = sqrt(len);
QuatX /= len;
QuatY /= len;
QuatZ /= len;
QuatW /= len;
}
}

void quatToMatrix(float mat[16])
{
float X = QuatX, Y = QuatY, Z = QuatZ, W = QuatW;
float xx, xy, xz, xw, yy, yz, yw, zz, zw;

xx = X * X;
xy = X * Y;
xz = X * Z;
xw = X * W;
yy = Y * Y;
yz = Y * Z;
yw = Y * W;
zz = Z * Z;
zw = Z * W;
mat[0] = 1 - 2 * ( yy + zz );
mat[1] = 2 * ( xy - zw );
mat[2] = 2 * ( xz + yw );
mat[4] = 2 * ( xy + zw );
mat[5] = 1 - 2 * ( xx + zz );
mat[6] = 2 * ( yz - xw );
mat[8] = 2 * ( xz - yw );
mat[9] = 2 * ( yz + xw );
mat[10] = 1 - 2 * ( xx + yy );
mat[3] = mat[7] = mat[11] = mat[12] = mat[13] = mat[14] = 0;
mat[15] = 1;
}

In my update function i have something like

multQuat(sin(.05), 0, 0, cos(.5));

when i press up and each direction having its own thing.

in my display function i call the following before i draw my sphere where m is my 16 element matrix i am storing the rotation.

normalizeQuat();
quatToMatrix(m);
glMultMatrixf (m);

I am still not rotating right. It works if i move in the 8 directions from the origin. once i leave the origin and start to rotate into another direction i have a gimbal lock.

I am sorry for this long post but please can someone point me into the right direction?

Alfonse Reinheart
02-25-2011, 12:47 PM
when i press up and each direction having its own thing.

I don't understand what that means.

once i leave the origin and start to rotate into another direction i have a gimbal lock.

You can't have gimbal lock with what you're doing. You're not using gimbals, so it is physically impossible for you to lock them.

Try to explain exactly what you're seeing happening.

cytricks
02-25-2011, 01:35 PM
I am sorry, maybe i am using the wrong term. I am just frustrated.

What I meant is that when i press a direction the all rotates on that direction.

case GLUT_KEY_UP : multQuat(sin(.005), 0, 0, cos(.5));break;
case GLUT_KEY_DOWN : multQuat(sin(-.005), 0, 0,cos(-.005));break;
case GLUT_KEY_LEFT : multQuat(0, 0, sin(-.005),cos(-.005));break;
case GLUT_KEY_RIGHT : multQuat(0, 0, sin(.005), cos(.005));break;

That is what i meant.

What is happening is that when I move the sphere in the north, south, west, east and the four in between, It rotates how you would expect to see it.

That problem i am having is that is i rotate the ball 90 degrees about the x direction, then if i was to rotate it about the z direction it rotates about the y instead. I thought that was what gimbal lock was, im sorry.

My code in is my first post if you want to run it to see.

I understand how quaternion and rotation matrix works but i do not know if i am implementing them right.

**I know a way to make it work with just using the glRotate function but it is not a smooth rotation, every time you change direction it resets the orientation. I want to be able to smoothly rotate the sphere in any direction.

Alfonse Reinheart
02-25-2011, 03:00 PM
That problem i am having is that is i rotate the ball 90 degrees about the x direction, then if i was to rotate it about the z direction it rotates about the y instead.

You need to clarify which axes you're referring to. Your object, in model space, has its local XYZ axes. And then there are the world XYZ axes. Plus, the camera-space XYZ axes.

The code as you have set it up will rotate around the model local axes. If you want to rotate about the world axes, then you should do the quaternion multiplication on the other side. Which the page I linked you to explains. The key quote being:

In particular, pay attention to the difference between right multiplication and left multiplication. When you right-multiply, the offset orientation is in model space. When you left-multiply, the offset is in world space. Both of these can be useful for different purposes.

cytricks
02-25-2011, 03:48 PM
It would be the world's XYZ axes I believe. I have the ball on a plane and i want it to look like it is rolling on the plane.

I am pushed the ModelView matrix and popped it after i made the plane. I then multiplied by the quaternion right before I start drawing the sphere. I dont know if is the left multiple or right multiply problem.

This link has a build of what i am doing.

http://www.mediafire.com/?fr97gda4rc3gbar

Alfonse Reinheart
02-25-2011, 04:38 PM
It would be the world's XYZ axes I believe. I have the ball on a plane and i want it to look like it is rolling on the plane.

Then, as I said, "If you want to rotate about the world axes, then you should do the quaternion multiplication on the other side."

So do that.

cytricks
02-25-2011, 04:59 PM
DUDE I LOVE YOU!!!!!!!!!!!!!!!!!!!!!

NO HOMO BUT I HEART YOU!!!!

I was a little reluctant to believe i was doing it wrong but thank you! Thank you so much!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!