Improve precision of UnitQuaternion::angle (#569)
The previous implementation had stability problems for small angles due to the behaviour of the arccosine it used. In particular, it needs a hack to handle "cosines" greater than 1 and the smallest obtainable nonzero angle for e.g. f32 is acos(1-2^-22) = 0.00069... These problems can be fixed by using an arctangent-based formula.
This commit is contained in:
parent
b4d800f3e2
commit
74aefd9c23
|
@ -602,13 +602,7 @@ impl<N: Real> UnitQuaternion<N> {
|
|||
#[inline]
|
||||
pub fn angle(&self) -> N {
|
||||
let w = self.quaternion().scalar().abs();
|
||||
|
||||
// Handle inaccuracies that make break `.acos`.
|
||||
if w >= N::one() {
|
||||
N::zero()
|
||||
} else {
|
||||
w.acos() * ::convert(2.0f64)
|
||||
}
|
||||
self.quaternion().imag().norm().atan2(w) * ::convert(2.0f64)
|
||||
}
|
||||
|
||||
/// The underlying quaternion.
|
||||
|
|
Loading…
Reference in New Issue