How to Fix Gimbal Lock in N-Dimensions

What causes gimbal lock?

Gimbal lock is the loss of a degree of freedom in a rotation system. It will always happen in any system that uses Euler angles, where you rotate your object by applying a fixed set of successive rotations.

  • Rotate the cubes with W,A,S,D and Q, E
  • R to reset
rotationAroundX = Matrix3.fromAxisAngle(angle1, Xaxis);
rotationAroundY = Matrix3.fromAxisAngle(angle2, Yaxis);
rotationAroundZ = Matrix3.fromAxisAngle(angle3, Zaxis);
cubeRotation = rotationAroundX * rotationAroundY * rotationAroundZ;
rotationAroundX = Quaternion.fromAxisAngle(angle1, Xaxis);
rotationAroundY = Quaternion.fromAxisAngle(angle2, Yaxis);
rotationAroundZ = Quaternion.fromAxisAngle(angle3, Zaxis);
cubeRotation = rotationAroundX * rotationAroundY * rotationAroundZ;

How do you fix gimbal lock?

To fix gimbal lock, we must avoid modelling this physical gimbal system.

  1. Construct a quaternion that describes a rotation around whatever axis we want, and the angle to rotate by.
  2. Multiply that by the object’s current rotation as represented by a quaternion.
  3. Take the result and overwrite it back into the object’s current stored rotation.
// We want to rotate by 0.05 radians in this frame.
rotationThisFrame = Quaternion.fromAxisAngle(0.05, arbitraryAxis);
cubeRotation = cubeRotation * rotationThisFrame;
rotationThisFrame = Matrix3.fromAxisAngle(0.05, arbitraryAxis);cubeRotation = cubeRotation * rotationThisFrame;

Generalizing to N-dimensions

To generalize this solution to higher dimensions we need two things:

  • A way to represent rotations. So far in 3D we’ve used 3x3 matrices and quaternions.
  • A way to describe a rotation around an arbitrary axis.
rotationThisFrame = Matrix4.fromAxisAngle(0.05, arbitraryAxis);cubeRotation = cubeRotation * rotationThisFrame;
// Check which key(s) were pressed. In this frame, only the key for rotating in the XZ plane was pressed, so the rXZ 4x4 matrix gets a non-zero angle. rXY = Matrix4.fromXYRotation(0);
rXZ = Matrix4.fromXZRotation(0.05);
rYZ = Matrix4.fromYZRotation(0);
rXW = Matrix4.fromXWRotation(0);
rYW = Matrix4.fromYWRotation(0);
rZW = Matrix4.fromZWRotation(0);
rotationThisFrame = rXY * rXZ * rYZ * XW * rYW * rZW;cubeRotation = cubeRotation * rotationThisFrame;
// Check which key(s) were pressed. In this frame, only the key for the rotating in the XZ plane was pressed, so we add 0.05 to angle2.angle2 += 0.05;rXY = Matrix4.fromXYRotation(angle1);
rXZ = Matrix4.fromXZRotation(angle2);
rYZ = Matrix4.fromYZRotation(angle3);
rXW = Matrix4.fromXWRotation(angle4);
rYW = Matrix4.fromYWRotation(angle5);
rZW = Matrix4.fromZWRotation(angle6);
cubeRotation = rXY * rXZ * rYZ * XW * rYW * rZW;

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Omar Shehata

Omar Shehata

Graphics programmer working on maps. I love telling stories and it's why I do what I do, from making games, to teaching & writing. https://omarshehata.me/