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.