1use crate::VectorSpace;
2use num_traits::real::Real;
3
4pub trait InnerSpace: VectorSpace {
6 fn scalar(self, other: Self) -> Self::Scalar;
8
9 #[inline]
14 fn magnitude2(self) -> Self::Scalar {
15 self.scalar(self)
16 }
17
18 #[inline]
20 fn magnitude(self) -> Self::Scalar {
21 self.magnitude2().sqrt()
22 }
23
24 #[inline]
26 fn normalize(self) -> Self {
27 self / self.magnitude()
28 }
29
30 #[inline]
32 fn angle(self, other: Self) -> Self::Scalar {
33 (self.scalar(other) / (self.magnitude() * other.magnitude())).acos()
34 }
35
36 #[inline]
38 fn with_magnitude(self, magnitude: Self::Scalar) -> Self {
39 self * (magnitude / self.magnitude())
40 }
41
42 #[inline]
44 fn with_direction(self, dir: Self) -> Self {
45 dir * self.magnitude()
46 }
47
48 #[inline]
50 fn query_axis(self, dir: Self) -> Self::Scalar {
51 self.scalar(dir.normalize())
52 }
53
54 #[inline]
56 fn normalized_project(self, dir: Self) -> Self {
57 dir * self.scalar(dir)
58 }
59
60 #[inline]
62 fn project(self, dir: Self) -> Self {
63 self.normalized_project(dir.normalize())
64 }
65
66 #[inline]
68 fn normalized_reject(self, dir: Self) -> Self {
69 self - self.normalized_project(dir)
70 }
71
72 #[inline]
74 fn reject(self, dir: Self) -> Self {
75 self.normalized_reject(dir.normalize())
76 }
77
78 #[inline]
80 fn normalized_reflect(self, dir: Self) -> Self {
81 let proj = self.normalized_project(dir);
82 proj + proj - self
83 }
84
85 #[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}