From 74aefd9c23dadd12ee654c7d0206b0a96d22040c Mon Sep 17 00:00:00 2001 From: Simon Puchert Date: Sun, 31 Mar 2019 10:32:34 +0200 Subject: [PATCH] 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. --- src/geometry/quaternion.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/geometry/quaternion.rs b/src/geometry/quaternion.rs index 6460a446..4a2007e0 100644 --- a/src/geometry/quaternion.rs +++ b/src/geometry/quaternion.rs @@ -602,13 +602,7 @@ impl UnitQuaternion { #[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.