Dayaan M. answered 22d
Trigonometry Tutor with a Bachelor's in Computer Science, 5.0 Rated
Gimbal lock is easiest to see if you just multiply the three matrices out and then set the middle angle to 90 degrees. Nothing mysterious happens; one of your three knobs quietly stops doing anything new.
Take the common yaw-pitch-roll convention, R = Rz(ψ) Ry(θ) Rx(φ):
Rz(ψ) = [[cosψ, -sinψ, 0], [sinψ, cosψ, 0], [0, 0, 1]]
Ry(θ) = [[cosθ, 0, sinθ], [0, 1, 0], [-sinθ, 0, cosθ]]
Rx(φ) = [[1, 0, 0], [0, cosφ, -sinφ], [0, sinφ, cosφ]]
Multiply them and the product is
[[cosψcosθ, sinφsinθcosψ - sinψcosφ, sinφsinψ + sinθcosφcosψ],
[sinψcosθ, sinφsinψsinθ + cosφcosψ, -sinφcosψ + sinψsinθcosφ],
[-sinθ, sinφcosθ, cosφcosθ]]
Now set θ = 90°. Then cosθ = 0 and sinθ = 1, so the whole first column and the rest of the bottom row collapse, and every surviving entry contains sinφcosψ ± cosφsinψ or cosφcosψ ± sinφsinψ. Those are exactly the angle-sum identities from trigonometry:
sinφcosψ - cosφsinψ = sin(φ - ψ)
cosφcosψ + sinφsinψ = cos(φ - ψ)
so the matrix becomes
[[0, sin(φ - ψ), cos(φ - ψ)],
[0, cos(φ - ψ), -sin(φ - ψ)],
[-1, 0, 0]]
That is the whole phenomenon. φ and ψ no longer appear separately anywhere in the matrix. Only their difference does. Yaw by 30 and roll by 10 produces the identical orientation to yaw by 0 and roll by -20, and to yaw by 100 and roll by 80. You still have three numbers, but they only reach a two-parameter family of orientations, so you have lost a degree of freedom. (If you set θ = -90° instead you get the same picture with φ + ψ in place of φ - ψ.)
I checked this symbolically before posting, and also numerically: holding φ - ψ fixed and sweeping ψ across 41 different values, all 41 rotation matrices agreed to 2.2e-16, which is just floating point noise.
Why it is a real problem and not just a curiosity. If you write the angular velocity as a matrix times (ψ', θ', φ'), the columns are the three axes you are actually rotating about: world z, then the pitch axis after yaw, then the roll axis after yaw and pitch. That matrix is
[[0, -sinψ, cosψcosθ], [0, cosψ, sinψcosθ], [1, 0, -sinθ]]
and its determinant works out to exactly -cosθ. So the map from Euler rates to actual angular velocity is invertible everywhere except θ = ±90°, where it drops from rank 3 to rank 2. Geometrically, the yaw axis and the roll axis have become the same line, which is why turning one knob is indistinguishable from turning the other.
The determinant also tells you the practical story. Its size is |cosθ|, so the condition number of that matrix grows like 1/cosθ. Here is what I measured:
θ = 30°: condition number 1.7
θ = 60°: 3.7
θ = 80°: 11.4
θ = 89°: 115
θ = 89.9°: 1146
θ = 90°: singular
That is why things get ugly before you reach the pole. At 89.9 degrees you are not locked yet, but solving for Euler rates amplifies error by about a thousand, so a camera or a gimbal starts whipping around on tiny input changes. The blow up is gradual, not a cliff.
Is quaternions the only workaround? No, and it helps to be precise about what the fix actually is. The root cause is not Euler angles specifically. It is that the set of 3D rotations cannot be covered by a single smooth three-number chart at all, so any three-angle scheme has degenerate configurations somewhere. Choosing a different convention only moves the bad set; a z-y-z convention locks when its middle angle is 0 or 180 instead of at ±90.
The real fix is to store orientation with more than three numbers and normalize:
Unit quaternions use four numbers with one constraint. They are compact, compose cheaply, and interpolate smoothly, which is why games and flight software use them.
Rotation matrices use nine numbers with six constraints. No singularity either, but you have to re-orthonormalize periodically to fight drift.
Axis-angle or a rotation vector is three numbers, and it is singular only at a 360 degree rotation, so it is fine for small incremental updates but not as a long-term store.
A reasonable pattern is to keep the orientation internally as a unit quaternion or matrix, and convert to yaw-pitch-roll only at the edges, for display or for user input. Then the degeneracy never touches your integration step. If you do have to read Euler angles out near the pole, use atan2 rather than asin and acos, and handle the θ = ±90 case explicitly by solving for φ - ψ as a single quantity, since that is genuinely all the information the matrix contains there.
One more thing worth knowing: quaternions have their own quirk, which is that q and -q represent the same rotation. That is not a lost degree of freedom like gimbal lock, just a double cover, but it will bite you if you compare orientations by comparing components, or if you interpolate without first flipping the sign to take the short way around.