Jump to content


Gimbal Lock with Quaternions?


  • You cannot reply to this topic
4 replies to this topic

#1 nico26

    New Member

  • Members
  • Pip
  • 3 posts

Posted 07 September 2005 - 02:10 PM

Hi!

I'm currently trying to write some code that executes a rotation around an arbitrary point in 3d space around two angles (alpha & delta), where alpha is the rotation around the global y axis and delta is the rotation around the global x axis.

At first I used this piece of code (point is the point to be rotated, origin the point to rotate about):
D3DXMatrixTranslation(&moveToOrigin, -origin.x, -origin.y, -origin.z);
D3DXMatrixTranslation(&moveBack, origin.x, origin.y, origin.z);

D3DXMatrixRotationY(&yMat, alpha_rad);
D3DXMatrixRotationX(&xMat, delta_rad);

totalMat = moveToOrigin * xMat * yMat * moveBack;
D3DXVec3TransformCoord(&result, &point, &totalMat);

The problem was that I got gimbal lock after e.g. rotating 90 degrees around y first and then rotating around x. Somehow it's clear that this causes a problem, since when I'm rotating around GLOBAL x after having rotated 90 degrees around y won't give any useful results.

Then I tried
D3DXQUATERNION qX, qY;
D3DXQuaternionRotationAxis(&qX, &D3DXVECTOR3(1.0f,0,0), delta_rad);
D3DXQuaternionRotationAxis(&qY, &D3DXVECTOR3(0,1.0f,0), alpha_rad);

D3DXMatrixAffineTransformation(&totalMat, 1.0f, &origin, &(qX*qY), NULL);

D3DXVec3TransformCoord(&result, &point, &totalMat);
since you can read everywhere sth. like "using quaternions avoids gimbal lock", but obviously in this example DX handles the rotations the same as in the first one, since my rotation problems remain exactly the same with this piece of code.

So how can this problem be solved? Is there an alternative to using global rotation axes? Or how can I get code that properly rotates a point around another given point in 3d space around alpha, delta without any gimbal lock problems?

Thanks & greetings in advance.
Nico.

#2 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 07 September 2005 - 02:28 PM

I think you misinterpreted the statement about quaternions avoiding gimbal lock. The statement is about interpolation between orientations. Interpolating euler angles can result in gimbal lock -because- you are rotating about global axes, as you're doing here. Interpolating quaternions don't have this problem as in that case you are in fact traveling the shortest arc on a 4d sphere that represents the possible 3d orientations.

But the problem is due to rotating about global axes, and using quaternions to rotate in the same way obviously gives the same results, as you have found :wink:

Solution: don't use the alpha and delta rotations, because those are simply euler angles. Where are these values coming from, and what exactly are you trying to accomplish?
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#3 nico26

    New Member

  • Members
  • Pip
  • 3 posts

Posted 07 September 2005 - 06:54 PM

.oisyn said:

Solution: don't use the alpha and delta rotations, because those are simply euler angles. Where are these values coming from, and what exactly are you trying to accomplish?

View Post


I want to be able to have spheres at arbitrary positions in my scene and I want to lock the camera on any one of these spheres, then have a camera mode where the camera rotates around the current sphere and is always centered onto this sphere.

The values come from the keyboard input from the user. He's supposed to be able to navigate the camera around the current sphere by using the cursor keys. These keys determine the values of alpha & delta.

I'm already using the local coordinate system of the camera to avoid gimbal lock for camera rotations and there it's no problem since I can update the local coordinate system of the cam in every frame.

I only don't know how to do a similar thing with the camera positions I have to calculate to achieve the effect I mentioned above.

Do you have a good idea how this could be done?

Thx, Nico.

#4 geon

    Senior Member

  • Members
  • PipPipPipPip
  • 893 posts

Posted 07 September 2005 - 10:33 PM

Then base your camera class on that requierment: Instead of storing location and lookAt, store a location, an orientation and a distance to the target.

This structure would be much easier to manipulate. Extracting the location, or even a coomplete camera matrix from this data is simple. (I have opengl code, if it is useful to you.)

#5 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 08 September 2005 - 07:39 AM

You could indeed, instead of keeping alpha and delta angles, just update your rotation matrix every frame by using the alpha and delta angles like you would normally, but only for that frame. So don't accumulate the alpha and delta values, but rotate the matrix every time you press a button or move the mouse or whatever. Or better yet, use a quaternion for your current orientation since they tend to be more numerically stable (and are easier to "normalize").
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users