How to Fix Gimbal Lock in N-Dimensions

What causes gimbal lock?

  • 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?

  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

  • 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;

--

--

--

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/

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

What is the Difference between RPA and BPM? — V2Solutions

: BOT ORCHESTRATION, BOTS, BPM, BUSINESS PROCESS MANAGEMENT, PROCESS AUTOMATION, PROCESS WORKFLOW, ROBOTIC PROCESS AUTOMATION

Introducing PolyEagle!

Kotlin extensions for Android View

How Crafting Sprint Goals Can Set Your Scrum Team’s Fate

Expo + react-native-firebase

Linux: how to zip files based on a find pattern

Reversing a .wav File in C#

S03E05 Tiddly pom on a rocket

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/

More from Medium

A Brief Introduction to Cinemachine and Timeline in Unity

Capturing Motion

3D Model Documentation

The simplest way to create a First Person Shooter! (Part 2)