This is a fix to the quaternion spherical linear interpolation to make it choose the shortest linear path which is the intended behavior in graphical animations.
However, because the covering is double (q and −q map to the same rotation), the rotation path may turn either the "short way" (less than 180°) or the "long way" (more than 180°). Long paths can be prevented by negating one end if the dot product, cos Ω, is negative, thus ensuring that −90° ≤ Ω ≤ 90°.
Hello,
This is a fix to the quaternion spherical linear interpolation to make it choose the shortest linear path which is the intended behavior in graphical animations.
This is glTF's tutorial by Khronos with a reference Slerp implementation (glTF trying to be the standard for 3D model): https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_007_Animations.md#linear
This is the cglm library (GLM being used by practically every 3D engine out there). https://github.com/recp/cglm/blob/master/include/cglm/quat.h#L701-L704
You'll find that my changes are in the same spirit as them. Added a test too.
This is a very well known problem. Wikipedia documents it here in detail: https://en.wikipedia.org/wiki/Slerp#Quaternion_Slerp
However, because the covering is double (q and −q map to the same rotation), the rotation path may turn either the "short way" (less than 180°) or the "long way" (more than 180°). Long paths can be prevented by negating one end if the dot product, cos Ω, is negative, thus ensuring that −90° ≤ Ω ≤ 90°.
I ran into this corner case using mathgl, my fork will stay up until the changes can get upstream: https://github.com/nitrix/mathgl/tree/fix/quat-slerp-closest
Cheers, Alex.