Angle calculation in RotationBetweenVectors
Closed this issue · 2 comments
I don't quite get it, why in RotationBetweenVectors
, the cosine of the angle is calculated as s * 0.5f
. The following is the relevant code, copied from the function:
float s = sqrt( (1+cosTheta)*2 );
float invs = 1 / s;
return quat(
s * 0.5f,
rotationAxis.x * invs,
rotationAxis.y * invs,
rotationAxis.z * invs
);
Why is it not quat(cosTheta * 0.5f, rotationAxis * sin(acos(cosTheta)) * 0.5f)
?
According to the explainations and the tool in [1], I would have thought that would be the way to go.
[1] Interactive quaternion exploration and learning tool by 3blue1brown and Ben Eater: https://eater.net/quaternions/video/intro
Okay, I was able to find out by myself.
I've read "The Shortest Arc Quaternion" in Game Programming Gems 1 by Stan Melax which this implementation is based on. There he states: "[...]the cross product [...] becomes small and potentially unstable when we try to normalize it[...]" and provides the solution which is numerically stable, resulting in the formulae used in the implementation of RotationBetweenVectors
.
This, however, brings me to another question: The implementation provided by Stan Melax does not suggest to use case differentiations like if (cosTheta < -1 + 0.001f)
. So, are these really neccessary?
Okay, I've tried it. It really is a problem. Your code is great! Thank you. This issue is closed.