mapping_algorithms/utils/
mod.rs1use nalgebra::{Const, DimMin, Point, RealField, SMatrix, Scalar};
25use num_traits::NumOps;
26
27#[cfg_attr(
28 feature = "tracing",
29 tracing::instrument("Calculate Distance Squared", skip_all, level = "trace")
30)]
31pub(crate) fn distance_squared<T, const N: usize>(point_a: &Point<T, N>, point_b: &Point<T, N>) -> T
32where
33 T: Copy + Default + NumOps + Scalar,
34{
35 point_a
36 .iter()
37 .zip(point_b.iter())
38 .map(|(&x, &y)| {
39 let diff = x - y;
40 diff * diff
41 })
42 .fold(T::default(), |acc, x| acc + x)
43}
44
45#[cfg_attr(
46 feature = "tracing",
47 tracing::instrument("Verify Matrix Determinant", skip_all, level = "info")
48)]
49pub(crate) fn verify_rotation_matrix_determinant<T, const N: usize>(
50 mut u: SMatrix<T, N, N>,
51 v_t: SMatrix<T, N, N>,
52) -> SMatrix<T, N, N>
53where
54 T: Copy + RealField,
55 Const<N>: DimMin<Const<N>, Output = Const<N>>,
56{
57 if (u * v_t).determinant() < T::zero() {
58 u.column_mut(N - 1)
59 .iter_mut()
60 .for_each(|element| *element *= T::one().neg()); }
62 u * v_t
63}
64
65#[cfg(test)]
66pub(crate) mod tests {
67 use super::*;
68 use nalgebra::{Matrix2, Point3};
69
70 #[test]
71 fn test_distance_squared() {
72 let point_a = Point3::new(1.0, 2.0, 3.0);
73 let point_b = Point3::new(4.0, 5.0, 6.0);
74 assert_eq!(distance_squared(&point_a, &point_b), 27.0)
75 }
76
77 #[test]
78 fn test_verify_rotation_matrix_determinant() {
79 let mat_a = Matrix2::new(2.0, 3.0, 2.0, 1.0);
80 let mat_b = Matrix2::new(-1.0, 0.0, 0.0, -1.0);
81
82 let regular_dot = mat_a * mat_b;
83 assert!(regular_dot.determinant() < 0.0);
84
85 let func_dot = verify_rotation_matrix_determinant(mat_a, mat_b);
86
87 assert!(func_dot.determinant() >= 0.0);
89 assert_eq!(func_dot.m12, -regular_dot.m12);
90 assert_eq!(func_dot.m22, -regular_dot.m22);
91 }
92}