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#[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 #[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 #[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 #[inline(always)]
42 pub fn norm(&self) -> T
43 where
44 T: MatrixDataType,
45 {
46 self.norm_sq().square_root()
47 }
48
49 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 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
163impl<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
180impl<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 #[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}