vector_space/
inner.rs

1use crate::VectorSpace;
2use num_traits::real::Real;
3
4/// This trait defines the scalar product and adds commom vector operations.
5pub trait InnerSpace: VectorSpace {
6    /// The scalar product.
7    fn scalar(self, other: Self) -> Self::Scalar;
8
9    /// The squared magnitude.
10    ///
11    /// This is more efficient than calculating the magnitude.
12    /// Useful if you need the squared magnitude anyway.
13    #[inline]
14    fn magnitude2(self) -> Self::Scalar {
15        self.scalar(self)
16    }
17
18    /// The magnitude of a vector.
19    #[inline]
20    fn magnitude(self) -> Self::Scalar {
21        self.magnitude2().sqrt()
22    }
23
24    /// The normalized vector.
25    #[inline]
26    fn normalize(self) -> Self {
27        self / self.magnitude()
28    }
29
30    /// The angle between two vectors.
31    #[inline]
32    fn angle(self, other: Self) -> Self::Scalar {
33        (self.scalar(other) / (self.magnitude() * other.magnitude())).acos()
34    }
35
36    /// Sets the magnitude of a vector.
37    #[inline]
38    fn with_magnitude(self, magnitude: Self::Scalar) -> Self {
39        self * (magnitude / self.magnitude())
40    }
41
42    /// Sets the direction of a vector.
43    #[inline]
44    fn with_direction(self, dir: Self) -> Self {
45        dir * self.magnitude()
46    }
47
48    /// The value of the vector along the specified axis.
49    #[inline]
50    fn query_axis(self, dir: Self) -> Self::Scalar {
51        self.scalar(dir.normalize())
52    }
53
54    /// Projects a vector onto an already normalized direction vector.
55    #[inline]
56    fn normalized_project(self, dir: Self) -> Self {
57        dir * self.scalar(dir)
58    }
59
60    /// Projects a vector onto an arbitraty direction vector.
61    #[inline]
62    fn project(self, dir: Self) -> Self {
63        self.normalized_project(dir.normalize())
64    }
65
66    /// Rejects a vector from an already normalized direction vector.
67    #[inline]
68    fn normalized_reject(self, dir: Self) -> Self {
69        self - self.normalized_project(dir)
70    }
71
72    /// Rejects a vector from an arbitraty direction vector.
73    #[inline]
74    fn reject(self, dir: Self) -> Self {
75        self.normalized_reject(dir.normalize())
76    }
77
78    /// Reflects a vector from an already normalized direction vector.
79    #[inline]
80    fn normalized_reflect(self, dir: Self) -> Self {
81        let proj = self.normalized_project(dir);
82        proj + proj - self
83    }
84
85    /// Reflects a vector from an arbitraty direction vector.
86    #[inline]
87    fn reflect(self, dir: Self) -> Self {
88        self.normalized_reflect(dir.normalize())
89    }
90}
91
92impl InnerSpace for f32 {
93    fn scalar(self, other: Self) -> Self {
94        self * other
95    }
96}
97impl InnerSpace for f64 {
98    fn scalar(self, other: Self) -> Self {
99        self * other
100    }
101}