From 4b300c60fc5e59d4e79c43697e34872bfa4f19a7 Mon Sep 17 00:00:00 2001 From: Dmitry Volynkin-Ewens Date: Mon, 29 Jul 2024 22:46:24 +1200 Subject: [PATCH 1/3] Added more test conditions to example. Doc test now failing. --- src/geometry/quaternion_construction.rs | 35 ++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/geometry/quaternion_construction.rs b/src/geometry/quaternion_construction.rs index 6de21bd57..dfbd51a29 100644 --- a/src/geometry/quaternion_construction.rs +++ b/src/geometry/quaternion_construction.rs @@ -814,14 +814,16 @@ where /// # use std::f32; /// # use nalgebra::{UnitQuaternion}; /// let q1 = UnitQuaternion::from_euler_angles(0.0, 0.0, 0.0); - /// let q2 = UnitQuaternion::from_euler_angles(-0.1, 0.0, 0.0); - /// let q3 = UnitQuaternion::from_euler_angles(0.1, 0.0, 0.0); + /// let q2 = UnitQuaternion::from_euler_angles(0.1, 0.0, 0.0); + /// let q3 = UnitQuaternion::from_euler_angles(0.2, 0.0, 0.0); /// /// let quat_vec = vec![q1, q2, q3]; /// let q_mean = UnitQuaternion::mean_of(quat_vec); /// /// let euler_angles_mean = q_mean.euler_angles(); - /// assert_relative_eq!(euler_angles_mean.0, 0.0, epsilon = 1.0e-7) + /// assert_relative_eq!(euler_angles_mean.0, 0.1, epsilon = 1.0e-7); + /// assert_relative_eq!(euler_angles_mean.1, 0.0, epsilon = 1.0e-7); + /// assert_relative_eq!(euler_angles_mean.2, 0.0, epsilon = 1.0e-7); /// ``` #[inline] pub fn mean_of(unit_quaternions: impl IntoIterator) -> Self @@ -925,4 +927,31 @@ mod tests { assert!(relative_eq!(x.into_inner().norm(), 1.0)) } } + + + + + + + + #[test] + fn mean_of_simple() { + // assert!(false); + + } + + + + + + + + + + + + + + + } From 76b3ffbe20104c3b3cff671631a0dca1b4e2ef3f Mon Sep 17 00:00:00 2001 From: Dmitry Volynkin-Ewens Date: Tue, 30 Jul 2024 00:00:10 +1200 Subject: [PATCH 2/3] Added failing tests. With values generated from python implementation of algorithm. mean_of not fixed yet. --- src/geometry/quaternion_construction.rs | 58 +++++++++++++++++-------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/src/geometry/quaternion_construction.rs b/src/geometry/quaternion_construction.rs index dfbd51a29..dabb28b5c 100644 --- a/src/geometry/quaternion_construction.rs +++ b/src/geometry/quaternion_construction.rs @@ -928,30 +928,54 @@ mod tests { } } - - - - - - + /// A single input value into mean_of should give back the same value. #[test] - fn mean_of_simple() { - // assert!(false); - - } - - - - - - - + fn mean_of_single() { + use nalgebra::UnitQuaternion; + let q1 = UnitQuaternion::from_euler_angles(0.1, 0.2, 0.3); + let quat_vec = vec![q1]; + let q_mean = UnitQuaternion::mean_of(quat_vec); + let euler_angles_mean = q_mean.euler_angles(); + assert_relative_eq!(euler_angles_mean.0, 0.1, epsilon = 1.0e-7); + assert_relative_eq!(euler_angles_mean.1, 0.2, epsilon = 1.0e-7); + assert_relative_eq!(euler_angles_mean.2, 0.3, epsilon = 1.0e-7); + } + /// Three input values, with the mean outputs to be compared against + /// [another implementation](https://stackoverflow.com/a/49690919/1758759) + /// of the averaging algorithm. + #[test] + fn mean_of_three_values_1() { + use nalgebra::UnitQuaternion; + let q1 = UnitQuaternion::from_euler_angles(0.2, 0.1, 0.2); + let q2 = UnitQuaternion::from_euler_angles(0.6, 0.0, 0.5); + let q3 = UnitQuaternion::from_euler_angles(0.2, 0.2, 1.2); + let quat_vec = vec![q1, q2, q3]; + let q_mean = UnitQuaternion::mean_of(quat_vec); + let euler_angles_mean = q_mean.euler_angles(); + assert_relative_eq!(euler_angles_mean.0, 0.32674402, epsilon = 1.0e-7); + assert_relative_eq!(euler_angles_mean.1, 0.08907341, epsilon = 1.0e-7); + assert_relative_eq!(euler_angles_mean.2, 0.63291054, epsilon = 1.0e-7); + } + /// Similar to `mean_of_three_values_1` but has some negative values thrown in for good measure. + #[test] + fn mean_of_three_values_2() { + use nalgebra::UnitQuaternion; + let q1 = UnitQuaternion::from_euler_angles(-1.4, 2.0, 0.4); + let q2 = UnitQuaternion::from_euler_angles(2.3, 2.0, -0.4); + let q3 = UnitQuaternion::from_euler_angles(-0.2, -7.0, 0.6); + let quat_vec = vec![q1, q2, q3]; + let q_mean = UnitQuaternion::mean_of(quat_vec); + let euler_angles_mean = q_mean.euler_angles(); + assert_relative_eq!(euler_angles_mean.0, -0.55177751, epsilon = 1.0e-7); + assert_relative_eq!(euler_angles_mean.1, 0.96545842, epsilon = 1.0e-7); + assert_relative_eq!(euler_angles_mean.2, 1.93519699, epsilon = 1.0e-7); + } } From 7c22102d9dd11232a3264db4f83efe6692134466 Mon Sep 17 00:00:00 2001 From: Dmitry Volynkin-Ewens Date: Tue, 30 Jul 2024 00:01:12 +1200 Subject: [PATCH 3/3] Fixed mean_of function. Tests now working. --- src/geometry/quaternion_construction.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geometry/quaternion_construction.rs b/src/geometry/quaternion_construction.rs index dabb28b5c..57a37584f 100644 --- a/src/geometry/quaternion_construction.rs +++ b/src/geometry/quaternion_construction.rs @@ -849,10 +849,10 @@ where let max_eigenvector = eigen_matrix.eigenvectors.column(max_eigenvalue_index); UnitQuaternion::from_quaternion(Quaternion::new( + max_eigenvector[3].clone(), max_eigenvector[0].clone(), max_eigenvector[1].clone(), max_eigenvector[2].clone(), - max_eigenvector[3].clone(), )) } }