From db3d08f81a30a814891d6e961ce3067a4150510c Mon Sep 17 00:00:00 2001 From: est31 <MTest31@outlook.com> Date: Tue, 12 Mar 2019 09:00:23 +0100 Subject: [PATCH 1/4] Fix two compiler warnings Fixes #561 --- src/base/cg.rs | 3 ++- src/base/edition.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/base/cg.rs b/src/base/cg.rs index 5883e710..2787e80b 100644 --- a/src/base/cg.rs +++ b/src/base/cg.rs @@ -294,7 +294,8 @@ impl<N: Scalar + Ring, D: DimName, S: StorageMut<N, D, D>> SquareMatrix<N, D, S> { for i in 0..D::dim() { for j in 0..D::dim() - 1 { - self[(j, i)] += shift[j] * self[(D::dim() - 1, i)]; + let add = shift[j] * self[(D::dim() - 1, i)]; + self[(j, i)] += add; } } } diff --git a/src/base/edition.rs b/src/base/edition.rs index 32e2c1aa..d7aba78f 100644 --- a/src/base/edition.rs +++ b/src/base/edition.rs @@ -58,7 +58,7 @@ impl<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { for j in 0..ncols.value() { // FIXME: use unchecked column indexing let mut res = res.column_mut(j); - let mut src = self.column(j); + let src = self.column(j); for (destination, source) in irows.clone().enumerate() { unsafe { From d6b5c7f8f7d088baac39d63daa876e0d3ea34cce Mon Sep 17 00:00:00 2001 From: sebcrozet <developer@crozet.re> Date: Mon, 18 Mar 2019 11:24:40 +0100 Subject: [PATCH 2/4] Release v0.17.3 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 43323c94..553c8835 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nalgebra" -version = "0.17.2" +version = "0.17.3" authors = [ "Sébastien Crozet <developer@crozet.re>" ] description = "Linear algebra library with transformations and statically-sized or dynamically-sized matrices." From b4d800f3e2a430b20ea77435e7b8dfb2348e5d88 Mon Sep 17 00:00:00 2001 From: Samuel Hurel <samuel.hurel@gmail.com> Date: Sun, 24 Mar 2019 21:44:49 +0100 Subject: [PATCH 3/4] Fix matrix slerp function (#568) * Fix matrix slerp function * Adding slerp doc test --- src/base/matrix.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/base/matrix.rs b/src/base/matrix.rs index fcd53703..78b82ec5 100644 --- a/src/base/matrix.rs +++ b/src/base/matrix.rs @@ -1480,6 +1480,19 @@ impl<N: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, D: Dim, S: Stor impl<N: Real, D: Dim, S: Storage<N, D>> Unit<Vector<N, D, S>> { /// Computes the spherical linear interpolation between two unit vectors. + /// + /// # Examples: + /// + /// ``` + /// # use nalgebra::geometry::UnitQuaternion; + /// + /// let q1 = UnitQuaternion::from_euler_angles(std::f32::consts::FRAC_PI_4, 0.0, 0.0); + /// let q2 = UnitQuaternion::from_euler_angles(-std::f32::consts::PI, 0.0, 0.0); + /// + /// let q = q1.slerp(&q2, 1.0 / 3.0); + /// + /// assert_eq!(q.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0)); + /// ``` pub fn slerp<S2: Storage<N, D>>( &self, rhs: &Unit<Vector<N, D, S2>>, @@ -1513,7 +1526,7 @@ impl<N: Real, D: Dim, S: Storage<N, D>> Unit<Vector<N, D, S>> { return Some(Unit::new_unchecked(self.clone_owned())); } - let hang = c_hang.acos(); + let hang = c_hang.abs().acos(); let s_hang = (N::one() - c_hang * c_hang).sqrt(); // FIXME: what if s_hang is 0.0 ? The result is not well-defined. @@ -1522,7 +1535,7 @@ impl<N: Real, D: Dim, S: Storage<N, D>> Unit<Vector<N, D, S>> { } else { let ta = ((N::one() - t) * hang).sin() / s_hang; let tb = (t * hang).sin() / s_hang; - let res = &**self * ta + &**rhs * tb; + let res = &**self * ta + &**rhs * tb * c_hang.signum(); Some(Unit::new_unchecked(res)) } From 74aefd9c23dadd12ee654c7d0206b0a96d22040c Mon Sep 17 00:00:00 2001 From: Simon Puchert <simonpuchert@alice.de> Date: Sun, 31 Mar 2019 10:32:34 +0200 Subject: [PATCH 4/4] 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<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.