Interpolate Between Two Quaternions The Long Way
We can do a slerp interpolation between two quaternions like this:
quat slerp(quat q1, quat q2, float t) {
float angle = acos(dotProduct(q1, q2));
float denom = sin(angle);
//check if denom is zero
return (q1*sin((1-t)*angle)+q2*sin(t*angle))/denom;
}
This will interpolate between the two quaternions the shortest way. However there's also a long way to interpolate between quaternions. As seen in the image below (source Maya).
How do we interpolate the long way?
Answer
The nature of unit quaternions and the way they map to 3D rotations means they can describe each 3D rotation value in two ways - as q(r, v')
and as q(-r, -v')
(imagine them as axis-angle rotations - inverting both the axis and the angle leads to the same 3D rotation).
Quaternions are actually points on a 4D unit spherical surface, and these two values represent anti-podal points on that sphere.
For a slerp (or nlerp) of two quaternions to follow the shortest path, the corresponding 4D points have to lie on the same hemisphere of the 4D sphere (this is also the reason why a weighted average of more than 2 quaternions doesn't have a unique solution). This maps to a non-negative dot product, and is usually something tested for in the interpolation code.
Simply negating one of the source quaternions will give you a point "on the opposite side of the 4D sphere", and lead to interpolation "the long way around" (and explains why negating the interpolation parameter leads to the same result).
Related Questions
- → Comparing two large files are taking over four hours
- → Setting JSON node name to variable value
- → Compiling GLUT using Emscripten
- → Evaluate check box from a scanned image in node.js
- → Find an easy web server framework for mobile game
- → my https C++ code doesn't work on some sites (binance)
- → Error while opening pivx wallet on ubuntu
- → Why sending a POST by AJAX is interpreted by the HTTP Server as OPTIONS and sending by CURL is effectively a PUT?
- → Python reading in one line multiple types for a calculator
- → How do I properly pass an argument to a function
- → Accessing Websql database with Qt
- → Using Mysql C API for c++ codes
- → How do I set constants at run-time in a c++ header file, imported through Cython?