This last week of work mainly dealt with the nitty-gritty issues of the Euler angle representation. Of all the representations so far this has to be the one most fraught with dangers and pitfalls, mainly because of one thing: Gimbal Lock
Gimbal lock refers to the loss of a degree of freedom in a three-gimbal mechanism. This happens when to of the three axes are driven into a parallel configuration.
While implementing the `as_euler` function this led to a host of problems. Firstly, extening the algorithm mentioned in this paper to extrinsic rotations required careful thinking, and experimentation in itself.
Since we have the loss of a degree of freedom, it is not possible to uniquely determine all three angles. Additionally, the numerical instability means that making even tiny tweaks (such as not reversing the angle sequence returned by the algorithm for adapting to extrinsic rotations), which should work in theory, lead to failures by changing the sign of small quantities close to zero.
Since Euler angles are not unique, we had to decide a range of angles that we were allowed to return. Enforcing those restrictions led to another insight: the range of allowed Euler angles is determined by the choice of axes that we rotate about.
We chose to constrain the first and third angles in the range [-180, 180]. This covers the full circle and presented no issues.
Then we chose to constrain the second angle to [-90, 90] degrees. Again, this presented no issues in theory but we realised that this constraint cannot represent the full range of rotations when the first and third axes are parallel; that realization made us enforce a restriction within [0, 180] degrees in those cases.
All of the above insights are the result of a time consuming process of experimentation, trying to tease apart the algorithm, in order to extend it for our purposes.
This function will conclude the representation part of the class and will give way to cooler stuff like applications, compositions, and inversion in the coming weeks.