diff --git a/src/structs/quaternion.rs b/src/structs/quaternion.rs index 52c7b26d..504066b6 100644 --- a/src/structs/quaternion.rs +++ b/src/structs/quaternion.rs @@ -570,24 +570,24 @@ impl Arbitrary for UnitQuaternion { impl Quaternion { /// Compute the exponential of a quaternion. - /// - /// This function yields a `UnitQuaternion`. - pub fn exp(&self) -> UnitQuaternion { - let v = Vector3::new(self.i, self.j, self.k); - let n = v.norm(); - let z = v / n * n.sin(); - - UnitQuaternion::new_with_quaternion(Quaternion::new(n.cos(), z[0], z[1], z[2])) + pub fn exp(&self) -> Self { + let v = *self.vector(); + let nn = v.norm_squared(); + + if nn.is_zero() { + ::one() + } else { + let n = nn.sqrt(); + let nv = v / n * n.sin(); + Quaternion::new(n.cos(), nv.x, nv.y, nv.z) + } } -} -impl UnitQuaternion { - /// Compute the natural logarithm (a.k.a ln()) of a unit quaternion. + /// Compute the natural logarithm (a.k.a ln()) of a quaternion. /// /// Becareful, this function yields a `Quaternion`, losing the unit property. - pub fn log(&self) -> Quaternion { - let q = self.quaternion(); - (Quaternion { w: 0., .. *q }).normalize() * q.w.acos() + pub fn log(&self) -> Self { + (Quaternion { w: 0., .. *self }).normalize() * self.w.acos() } /// Raise the quaternion to a given floating power.