marg_orientation/
vector3.rs

1use crate::accelerometer_reading::AccelerometerReading;
2use crate::magnetometer_reading::MagnetometerReading;
3use core::borrow::Borrow;
4use core::fmt::{Debug, Formatter};
5use core::ops::{Add, Mul, Neg, Sub};
6use minikalman::matrix::MatrixDataType;
7use uniform_array_derive::UniformArray;
8
9/// A three-dimensional vector.
10#[derive(UniformArray, Copy)]
11#[cfg_attr(test, ensure_uniform_type::ensure_uniform_type)]
12#[repr(C)]
13pub struct Vector3<T> {
14    pub x: T,
15    pub y: T,
16    pub z: T,
17}
18
19impl<T> Vector3<T> {
20    /// Initializes a new [`Vector3`] instance.
21    #[inline(always)]
22    pub const fn new(x: T, y: T, z: T) -> Self {
23        Self { x, y, z }
24    }
25}
26
27impl<T> Vector3<T> {
28    /// Calculates the squared vector length.
29    #[inline(always)]
30    #[doc(alias = "length")]
31    pub fn norm_sq(&self) -> T
32    where
33        T: Clone + Mul<T, Output = T> + Add<T, Output = T>,
34    {
35        (self.x.clone() * self.x.clone())
36            + (self.y.clone() * self.y.clone())
37            + (self.z.clone() * self.z.clone())
38    }
39
40    /// Calculates the vector length, i.e. its norm.
41    #[inline(always)]
42    pub fn norm(&self) -> T
43    where
44        T: MatrixDataType,
45    {
46        self.norm_sq().square_root()
47    }
48
49    /// Returns a normalized version of the vector.
50    pub fn normalized(&self) -> Self
51    where
52        T: MatrixDataType,
53    {
54        let norm_inv = self.norm().recip();
55        Self {
56            x: self.x * norm_inv,
57            y: self.y * norm_inv,
58            z: self.z * norm_inv,
59        }
60    }
61
62    /// Calculates the 3D vector cross product.
63    pub fn cross<V>(&self, rhs: V) -> Vector3<T>
64    where
65        T: MatrixDataType + Sub<Output = T> + Mul<Output = T>,
66        V: Borrow<Vector3<T>>,
67    {
68        let rhs = rhs.borrow();
69        Self {
70            x: self.y * rhs.z - self.z * rhs.y,
71            y: self.z * rhs.x - self.x * rhs.z,
72            z: self.x * rhs.y - self.y * rhs.x,
73        }
74    }
75}
76
77impl<T> Default for Vector3<T>
78where
79    T: Default,
80{
81    #[inline]
82    fn default() -> Self {
83        Self::new(Default::default(), Default::default(), Default::default())
84    }
85}
86
87impl<T> Clone for Vector3<T>
88where
89    T: Clone,
90{
91    fn clone(&self) -> Self {
92        Self {
93            x: self.x.clone(),
94            y: self.y.clone(),
95            z: self.z.clone(),
96        }
97    }
98}
99
100impl<T> Debug for Vector3<T>
101where
102    T: Debug,
103{
104    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
105        f.debug_tuple("Vector3")
106            .field(&self.x)
107            .field(&self.y)
108            .field(&self.z)
109            .finish()
110    }
111}
112
113impl<T> From<&AccelerometerReading<T>> for Vector3<T>
114where
115    T: Clone,
116{
117    #[inline]
118    fn from(value: &AccelerometerReading<T>) -> Self {
119        Self {
120            x: value.x.clone(),
121            y: value.y.clone(),
122            z: value.z.clone(),
123        }
124    }
125}
126
127impl<T> From<AccelerometerReading<T>> for Vector3<T> {
128    #[inline]
129    fn from(value: AccelerometerReading<T>) -> Self {
130        Self {
131            x: value.x,
132            y: value.y,
133            z: value.z,
134        }
135    }
136}
137
138impl<T> From<&MagnetometerReading<T>> for Vector3<T>
139where
140    T: Clone,
141{
142    #[inline]
143    fn from(value: &MagnetometerReading<T>) -> Self {
144        Self {
145            x: value.x.clone(),
146            y: value.y.clone(),
147            z: value.z.clone(),
148        }
149    }
150}
151
152impl<T> From<MagnetometerReading<T>> for Vector3<T> {
153    #[inline]
154    fn from(value: MagnetometerReading<T>) -> Self {
155        Self {
156            x: value.x,
157            y: value.y,
158            z: value.z,
159        }
160    }
161}
162
163/// Implements the unary negation.
164impl<T> Neg for Vector3<T>
165where
166    T: Neg<Output = T>,
167{
168    type Output = Vector3<T>;
169
170    #[inline]
171    fn neg(self) -> Self::Output {
172        Self {
173            x: -self.x,
174            y: -self.y,
175            z: -self.z,
176        }
177    }
178}
179
180/// Implements the vector dot product.
181impl<T> Mul<Vector3<T>> for Vector3<T>
182where
183    T: Mul<T, Output = T> + Clone + Add<T, Output = T>,
184{
185    type Output = T;
186
187    /// Calculates the inner product, also known as dot product.
188    #[inline]
189    fn mul(self, rhs: Vector3<T>) -> Self::Output {
190        (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z)
191    }
192}
193
194impl<T> Mul<T> for Vector3<T>
195where
196    T: Mul<T, Output = T> + Clone,
197{
198    type Output = Vector3<T>;
199
200    #[inline]
201    fn mul(self, rhs: T) -> Self::Output {
202        Self {
203            x: self.x * rhs.clone(),
204            y: self.y * rhs.clone(),
205            z: self.z * rhs.clone(),
206        }
207    }
208}
209
210impl<T> Sub<Vector3<T>> for Vector3<T>
211where
212    T: Sub<T, Output = T> + Clone,
213{
214    type Output = Vector3<T>;
215
216    #[inline]
217    fn sub(self, rhs: Vector3<T>) -> Self::Output {
218        Self {
219            x: self.x - rhs.x,
220            y: self.y - rhs.y,
221            z: self.z - rhs.z,
222        }
223    }
224}
225
226impl<T> Sub<T> for Vector3<T>
227where
228    T: Sub<T, Output = T> + Clone,
229{
230    type Output = Vector3<T>;
231
232    #[inline]
233    fn sub(self, rhs: T) -> Self::Output {
234        Self {
235            x: self.x - rhs.clone(),
236            y: self.y - rhs.clone(),
237            z: self.z - rhs.clone(),
238        }
239    }
240}
241
242impl<T> From<Vector3<T>> for (T, T, T) {
243    fn from(value: Vector3<T>) -> Self {
244        (value.x, value.y, value.z)
245    }
246}
247
248#[cfg(test)]
249mod test {
250    use super::*;
251
252    #[test]
253    fn test_index() {
254        let vec = Vector3::<f32> {
255            x: 1.0,
256            y: 2.0,
257            z: 3.0,
258        };
259
260        assert_eq!(vec[0], 1.0);
261        assert_eq!(vec[1], 2.0);
262        assert_eq!(vec[2], 3.0);
263    }
264
265    #[test]
266    fn test_length() {
267        let vec = Vector3::<f32> {
268            x: 1.0,
269            y: 2.0,
270            z: 3.0,
271        };
272
273        assert_eq!(vec.norm_sq(), 14.0);
274        assert_eq!(vec.norm(), 14.0_f32.sqrt());
275    }
276}