parry3d/math/
vector_ext.rs

1//! Vector extension trait for glam types.
2
3use crate::math::{Matrix, Real, Vector};
4
5#[cfg(not(feature = "std"))]
6use simba::scalar::ComplexField;
7
8/// Extension trait for glam vector types to provide additional functionality.
9pub trait VectorExt: Sized + Copy {
10    /// Creates a vector with the i-th component set to `val` and all others to zero.
11    fn ith(i: usize, val: Real) -> Self;
12
13    /// Computes the angle between two vectors in radians.
14    fn angle(self, other: Self) -> Real;
15
16    /// Computes the kronecker product between two vectors.
17    fn kronecker(self, other: Self) -> Matrix;
18}
19
20impl VectorExt for Vector {
21    #[inline]
22    #[cfg(feature = "dim2")]
23    fn ith(i: usize, val: Real) -> Self {
24        match i {
25            0 => Self::new(val, 0.0),
26            1 => Self::new(0.0, val),
27            _ => Self::ZERO,
28        }
29    }
30    #[inline]
31    #[cfg(feature = "dim3")]
32    fn ith(i: usize, val: Real) -> Self {
33        match i {
34            0 => Self::new(val, 0.0, 0.0),
35            1 => Self::new(0.0, val, 0.0),
36            2 => Self::new(0.0, 0.0, val),
37            _ => Self::ZERO,
38        }
39    }
40
41    #[inline]
42    fn angle(self, other: Self) -> Real {
43        let dot = self.dot(other);
44        let len_self = self.length();
45        let len_other = other.length();
46        if len_self > 0.0 && len_other > 0.0 {
47            (dot / (len_self * len_other)).clamp(-1.0, 1.0).acos()
48        } else {
49            0.0
50        }
51    }
52
53    #[inline]
54    #[cfg(feature = "dim2")]
55    fn kronecker(self, other: Self) -> Matrix {
56        Matrix::from_cols(self * other.x, self * other.y)
57    }
58
59    #[inline]
60    #[cfg(feature = "dim3")]
61    fn kronecker(self, other: Self) -> Matrix {
62        Matrix::from_cols(self * other.x, self * other.y, self * other.z)
63    }
64}