feo_math/linear_algebra/
vector3.rs

1use std::ops::Rem;
2
3use crate::{F32Fmt, One, SignOps, /*Sum,*/ Two, Zero};
4
5use {
6    super::Vector,
7    crate::Construct,
8    std::{
9        fmt, 
10        ops::{Add, Div, Sub, Mul, Neg}
11    }
12};
13
14/// A 3D vector
15#[derive(PartialEq, Clone, Copy)]
16pub struct Vector3<T>(pub T, pub T, pub T);
17
18impl<T> fmt::Debug for Vector3<T>
19where T: fmt::Debug + Copy {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        write!(f, "({:?}, {:?}, {:?})", self.0, self.1, self.2)
22    }
23}
24
25impl<T> Vector3<T> {
26    /// A clean way of making a Vector3 <x, y, z>
27    /// # Arguments
28    /// * `x` - The x direction scalar .0
29    /// * `y` - The y direction scalar .1
30    /// * `z` - The z direction scalar .2
31    pub fn new(x: T, y: T, z: T) -> Self
32    where T: Construct<T> {
33        Vector3(x, y, z)
34    }
35
36    /// Returns the Vector3<T> normalized to a given length
37    /// # Arguments
38    /// * `length` - The length to normalize to. Default is 1
39    /// # Examples
40    /// ```rust
41    /// use feo_math::linear_algebra::vector3::Vector3;
42    /// let vec = Vector3::new(2, 0, 0);
43    /// assert_eq!(vec.normalize(Some(5)), Vector3::new(5, 0, 0));
44    /// assert_eq!(vec.normalize(None), Vector3::new(1, 0, 0));
45    /// ```
46    pub fn normalize(&self, length: Option<T>) -> Vector3<T>
47    where T: Mul<T, Output = T> + Div<T, Output = T> + Add<T, Output = T> + F32Fmt + Copy {
48        let s = self.norm();
49        match length {
50            Some(len) => Vector3(self.0 / s * len, self.1 / s * len, self.2 / s * len),
51            None => Vector3(self.0 / s, self.1 / s, self.2 / s),
52        }
53    }
54
55    /// Returns the magnitude, norm, or length of the vector denoted  `||v||`
56    /// # Examples
57    /// ```rust
58    /// use feo_math::linear_algebra::vector3::Vector3;
59    /// let vec = Vector3::new(2, 0, 0);
60    /// assert_eq!(vec.norm(), 2);
61    /// ```
62    #[inline]
63    pub fn norm(&self) -> T
64    where T: Add<T, Output = T> + Mul<T, Output = T> + F32Fmt + Copy {
65        (self.0 * self.0 + self.1 * self.1 + self.2 * self.2).sqrt()
66    }
67
68    /// Returns the unit vector of the vector denoted `Uv`
69    /// # Examples
70    /// ```rust
71    /// use feo_math::linear_algebra::vector3::Vector3;
72    /// let v = Vector3::new(1.0, 2.0, 3.0);
73    /// let Uv = v.unit_vector();
74    /// assert_eq!(Uv.norm(), 1.0);
75    /// ```
76    #[inline]
77    pub fn unit_vector(&self) -> Self
78    where Self: Div<T, Output = Self>, T: Add<T, Output = T> + Mul<T, Output = T> + F32Fmt + Copy {
79        *self / self.norm()
80    }
81
82    /// Returns the cross product of 2 Vector4s denoted `A x B`
83    /// A trick to know which direction the cross product vector
84    /// will be pointing is the right hand rule
85    /// ```text
86    /// side view
87    ///          ^\ a x b (pointing up)
88    /// a _______|| _________ arm (you)
89    ///       ///_  
90    ///      | \__  
91    ///      |
92    ///      b (pointing left)
93    /// ```
94    /// where your index finger is vector a pointing forwards along z
95    /// your middle finger is vector b pointing left along x
96    /// and your thumb is the cross product a x b pointing up
97    /// If you want to think in standard camera space terms use 
98    /// the left hand rule and note that your index finger is pointing 
99    /// along -z
100    /// # Arguments
101    /// * `a` - The first Vector4
102    /// * `b` - The second Vector4
103    /// # Examples
104    /// ```rust
105    /// use feo_math::linear_algebra::vector3::Vector3;
106    /// let a = Vector3(0, 0, -1);
107    /// let b = Vector3(-1, 0, 0);
108    /// assert_eq!(Vector3::cross_product(a, b), Vector3(0, 1, 0));
109    /// ```
110    pub fn cross_product(a: Self, b: Self) -> Self
111    where T: Mul<T, Output = T> + Sub<T, Output = T> + Copy {
112        Vector3(
113            (a.1 * b.2) - (a.2 * b.1),
114            (a.2 * b.0) - (a.0 * b.2),
115            (a.0 * b.1) - (a.1 * b.0)
116        )
117    }
118
119    /// Returns the dot product of 2 Vector4s denoted `A . B`
120    /// # Arguments
121    /// * `a` - The first Vector4
122    /// * `b` - The second Vector4
123    /// # Examples
124    /// ```rust
125    /// use feo_math::linear_algebra::vector3::Vector3;
126    /// let a = Vector3(0, 0, -1);
127    /// let b = Vector3(-1, 0, 0);
128    /// assert_eq!(Vector3::dot_product(a, b), 0);
129    /// ```
130    pub fn dot_product(a: Self, b: Self) -> T
131    where T: Mul<T, Output = T> + Add<T, Output = T> + Copy {
132        (a.0 * b.0) + (a.1 * b.1) + (a.2 * b.2)
133    }
134}
135
136impl<T> Construct<T> for Vector3<T> where T: Construct<T> {}
137impl<T> Vector<T> for Vector3<T> where T: Construct<T> {}
138
139impl<T> Add for Vector3<T> 
140where T: Add<T, Output = T> + Copy {
141    type Output = Self;
142
143    /// Vector
144    /// # Examples
145    /// ```
146    /// use feo_math::linear_algebra::vector3::Vector3;
147    /// let vec = Vector3::new(1, 2, 3);
148    /// let expected = Vector3::new(2, 4, 6);
149    /// assert_eq!(vec + vec, expected);
150    /// ```
151    fn add (self, rhs: Self) -> Self::Output{
152        Vector3(self.0 + rhs.0, self.1 + rhs.1, self.2 + rhs.2)
153    }
154}
155
156impl<T> Add<T> for Vector3<T> 
157where T: Add<T, Output = T> + Copy {
158    type Output = Self;
159
160    /// Element wise addition
161    /// # Examples
162    /// ```
163    /// use feo_math::linear_algebra::vector3::Vector3;
164    /// assert_eq!(Vector3(1, 3, 2) + 2, Vector3(3, 5, 4));
165    /// ```
166    fn add (self, rhs: T) -> Self::Output{
167        Vector3(self.0 + rhs, self.1 + rhs, self.2 + rhs)
168    }
169}
170
171impl<T> Sub for Vector3<T> 
172where T: Sub<T, Output = T> + Copy {
173    type Output = Self;
174
175    fn sub (self, rhs: Self) -> Self::Output{
176        Vector3(self.0 - rhs.0, self.1 - rhs.1, self.2 - rhs.2)
177    }
178}
179
180impl<T> Sub<T> for Vector3<T> 
181where T: Sub<T, Output = T> + Copy {
182    type Output = Self;
183
184    fn sub (self, rhs: T) -> Self::Output{
185        Vector3(self.0 - rhs, self.1 - rhs, self.2 - rhs)
186    }
187}
188
189impl<T> Mul for Vector3<T> 
190where T: Mul<T, Output = T> + Copy {
191    type Output = Self;
192
193    fn mul (self, rhs: Self) -> Self::Output{
194        Vector3(self.0 * rhs.0, self.1 * rhs.1, self.2 * rhs.2)
195    }
196}
197
198impl<T> Mul<T> for Vector3<T> 
199where T: Mul<T, Output = T> + Copy {
200    type Output = Self;
201
202    fn mul (self, rhs: T) -> Self::Output{
203        Vector3(self.0 * rhs, self.1 * rhs, self.2 * rhs)
204    }
205}
206
207impl<T> Div for Vector3<T>
208where T: Div<T, Output = T> + Copy {
209    type Output = Self;
210
211    fn div (self, rhs: Self) -> Self::Output{
212        Vector3(self.0 / rhs.0, self.1 / rhs.1, self.2 / rhs.2)
213    }
214}
215
216impl<T> Div<T> for Vector3<T> 
217where T: Div<T, Output = T> + Copy {
218    type Output = Self;
219
220    fn div (self, rhs: T) -> Self::Output {
221        Vector3(self.0 / rhs, self.1 / rhs, self.2 / rhs)
222    }
223}
224
225impl<T> Rem for Vector3<T>
226where T: Rem<T, Output = T> + Copy {
227    type Output = Self;
228
229    fn rem (self, rhs: Self) -> Self::Output {
230        Vector3(self.0 % rhs.0, self.1 % rhs.1, self.2 % rhs.2)
231    }
232}
233
234impl<T> Rem<T> for Vector3<T> 
235where T: Rem<T, Output = T> + Copy {
236    type Output = Self;
237
238    /// # Examples
239    /// ```rust
240    /// use feo_math::linear_algebra::vector3;
241    /// ```
242    fn rem (self, rhs: T) -> Self::Output {
243        Vector3(self.0 % rhs, self.1 % rhs, self.2 % rhs)
244    }
245}
246
247impl<T> Neg for Vector3<T> 
248where T: Neg<Output = T> + Copy {
249    type Output = Self;
250
251    fn neg(self) -> Self::Output {
252        Vector3(-self.0, -self.1, -self.2)
253    }
254}
255
256impl<T> Zero for Vector3<T> where T: Zero { const ZERO: Self = Vector3(T::ZERO, T::ZERO, T::ZERO); }
257impl<T> One for Vector3<T> where T: One { const ONE: Self = Vector3(T::ONE, T::ONE, T::ONE); }
258impl<T> Two for Vector3<T> where T: Two { const TWO: Self = Vector3(T::TWO, T::TWO, T::TWO); }
259
260impl<T> From<Vector3<T>> for [T; 3] 
261where T: Copy {
262    fn from(other: Vector3<T>) -> [T; 3]{
263        [other.0, other.1, other.2]
264    }
265}
266
267impl<T> From<[T; 3]> for Vector3<T> 
268where T: Copy{
269    fn from(other: [T; 3]) -> Self {
270        Vector3(other[0], other[1], other[2])
271    }
272}
273
274impl<T> F32Fmt for Vector3<T> 
275where   T: F32Fmt + Copy { 
276    type F32Fmt = Vector3<T::F32Fmt>;
277    #[inline]
278    fn intoF32Fmt(self) -> Self::F32Fmt {
279        Vector3(self.0.intoF32Fmt(), self.1.intoF32Fmt(), self.2.intoF32Fmt())
280    }
281    #[inline]
282    fn fromF32Fmt(f32_fmt: Self::F32Fmt) -> Self {
283        let vec = &f32_fmt;
284        Vector3(T::fromF32Fmt(vec.0), T::fromF32Fmt(vec.1), T::fromF32Fmt(f32_fmt.2))
285    }
286
287    /// Element wise square root
288    fn sqrt(self) -> Self {
289       Vector3(self.0.sqrt(), self.1.sqrt(), self.2.sqrt())
290    }
291
292    fn cbrt(self) -> Self { 
293        Vector3(self.0.cbrt(), self.1.cbrt(), self.2.cbrt())
294    }
295
296    fn f32_const_mul(self, constant: f32) -> Self {
297        Vector3(self.0.f32_const_mul(constant), self.1.f32_const_mul(constant), self.2.f32_const_mul(constant))
298    }
299
300    fn sin_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
301        todo!()
302    }
303
304    fn cos_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
305        todo!()
306    }
307
308    fn tan_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
309        todo!()
310    }
311
312    fn asin_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
313        todo!()
314    }
315
316    fn acos_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
317        todo!()
318    }
319
320    fn atan_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
321        todo!()
322    }
323
324    fn atan2_mul(self, _other: Self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
325        todo!()
326    }
327
328    fn sinh_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
329        todo!()
330    }
331
332    fn cosh_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
333        todo!()
334    }
335
336    fn tanh_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
337        todo!()
338    }
339}
340impl<T> SignOps for Vector3<T> {
341    fn ptcopysign(self, _sign: Self) -> Self {
342        todo!()
343    }
344
345    fn ptsignum(self) -> i8 {
346        todo!()
347    }
348
349    fn abs(self) -> Self {
350        todo!()
351    }
352}