parse_monitors/
vector.rs

1use std::{
2    fmt,
3    ops::{Add, AddAssign, Div, Index, IndexMut, Sub},
4};
5
6#[derive(Default, Debug, Clone)]
7pub struct Vector {
8    pub x: Option<f64>,
9    pub y: Option<f64>,
10    pub z: Option<f64>,
11}
12impl Vector {
13    pub fn zero() -> Self {
14        Self {
15            x: Some(0f64),
16            y: Some(0f64),
17            z: Some(0f64),
18        }
19    }
20    pub fn magnitude(&self) -> Option<f64> {
21        if let Some((x, y, z)) = self.as_tuple() {
22            Some((x * x + y * y + z * z).sqrt())
23        } else {
24            None
25        }
26    }
27    pub fn from_x(value: f64) -> Self {
28        Self {
29            x: Some(value),
30            ..Default::default()
31        }
32    }
33    pub fn from_y(value: f64) -> Self {
34        Self {
35            y: Some(value),
36            ..Default::default()
37        }
38    }
39    pub fn from_z(value: f64) -> Self {
40        Self {
41            z: Some(value),
42            ..Default::default()
43        }
44    }
45    pub fn as_tuple(&self) -> Option<(&f64, &f64, &f64)> {
46        match self {
47            Vector {
48                x: Some(a1),
49                y: Some(a2),
50                z: Some(a3),
51            } => Some((a1, a2, a3)),
52            _ => None,
53        }
54    }
55    pub fn into_tuple(self) -> Option<(f64, f64, f64)> {
56        match self {
57            Vector {
58                x: Some(a1),
59                y: Some(a2),
60                z: Some(a3),
61            } => Some((a1, a2, a3)),
62            _ => None,
63        }
64    }
65    pub fn as_array(&self) -> [&f64; 3] {
66        match self {
67            Vector {
68                x: Some(a1),
69                y: Some(a2),
70                z: Some(a3),
71            } => Ok([a1, a2, a3]),
72            _ => Err(""),
73        }
74        .unwrap()
75    }
76    pub fn cross(&self, other: &Vector) -> Option<Vector> {
77        if let (Some((a1, a2, a3)), Some((b1, b2, b3))) = (self.as_tuple(), other.as_tuple()) {
78            Some(Vector {
79                x: Some(a2 * b3 - a3 * b2),
80                y: Some(a3 * b1 - a1 * b3),
81                z: Some(a1 * b2 - a2 * b1),
82            })
83        } else {
84            None
85        }
86    }
87    pub fn norm_squared(&self) -> Option<f64> {
88        if let Some((a1, a2, a3)) = self.as_tuple() {
89            Some(a1 * a1 + a2 * a2 + a3 * a3)
90        } else {
91            None
92        }
93    }
94}
95impl Sub<Vector> for &Vector {
96    type Output = Option<Vector>;
97
98    fn sub(self, rhs: Vector) -> Self::Output {
99        if let (Some((a1, a2, a3)), Some((b1, b2, b3))) = (self.as_tuple(), rhs.as_tuple()) {
100            Some(Vector {
101                x: Some(a1 - b1),
102                y: Some(a2 - b2),
103                z: Some(a3 - b3),
104            })
105        } else {
106            None
107        }
108    }
109}
110impl Sub for Vector {
111    type Output = Option<Vector>;
112
113    fn sub(self, rhs: Self) -> Self::Output {
114        if let (Some((a1, a2, a3)), Some((b1, b2, b3))) = (self.as_tuple(), rhs.as_tuple()) {
115            Some(Vector {
116                x: Some(a1 - b1),
117                y: Some(a2 - b2),
118                z: Some(a3 - b3),
119            })
120        } else {
121            None
122        }
123    }
124}
125impl Add for &Vector {
126    type Output = Vector;
127
128    fn add(self, rhs: Self) -> Self::Output {
129        if let (Some((a1, a2, a3)), Some((b1, b2, b3))) = (self.as_tuple(), rhs.as_tuple()) {
130            Vector {
131                x: Some(a1 + b1),
132                y: Some(a2 + b2),
133                z: Some(a3 + b3),
134            }
135        } else {
136            self.clone()
137        }
138    }
139}
140impl Add for Vector {
141    type Output = Vector;
142
143    fn add(self, rhs: Self) -> Self::Output {
144        if let (Some((a1, a2, a3)), Some((b1, b2, b3))) = (self.as_tuple(), rhs.as_tuple()) {
145            Vector {
146                x: Some(a1 + b1),
147                y: Some(a2 + b2),
148                z: Some(a3 + b3),
149            }
150        } else {
151            self
152        }
153    }
154}
155impl Add<&Vector> for Vector {
156    type Output = Vector;
157
158    fn add(self, rhs: &Vector) -> Self::Output {
159        if let (Some((a1, a2, a3)), Some((b1, b2, b3))) = (self.as_tuple(), rhs.as_tuple()) {
160            Vector {
161                x: Some(a1 + b1),
162                y: Some(a2 + b2),
163                z: Some(a3 + b3),
164            }
165        } else {
166            self
167        }
168    }
169}
170impl AddAssign<&Vector> for &mut Vector {
171    fn add_assign(&mut self, other: &Vector) {
172        if let (Some((a1, a2, a3)), Some((b1, b2, b3))) = (self.as_tuple(), other.as_tuple()) {
173            **self = Vector {
174                x: Some(a1 + b1),
175                y: Some(a2 + b2),
176                z: Some(a3 + b3),
177            }
178        }
179    }
180}
181impl AddAssign<Vector> for &mut Vector {
182    fn add_assign(&mut self, other: Vector) {
183        if let (Some((a1, a2, a3)), Some((b1, b2, b3))) = (self.as_tuple(), other.as_tuple()) {
184            **self = Vector {
185                x: Some(a1 + b1),
186                y: Some(a2 + b2),
187                z: Some(a3 + b3),
188            }
189        }
190    }
191}
192impl Div<f64> for Vector {
193    type Output = Option<Self>;
194
195    fn div(self, rhs: f64) -> Self::Output {
196        if let Some((a1, a2, a3)) = self.as_tuple() {
197            Some(Vector {
198                x: Some(a1 / rhs),
199                y: Some(a2 / rhs),
200                z: Some(a3 / rhs),
201            })
202        } else {
203            None
204        }
205    }
206}
207impl Div<f64> for &Vector {
208    type Output = Option<Vector>;
209
210    fn div(self, rhs: f64) -> Self::Output {
211        if let Some((a1, a2, a3)) = self.as_tuple() {
212            Some(Vector {
213                x: Some(a1 / rhs),
214                y: Some(a2 / rhs),
215                z: Some(a3 / rhs),
216            })
217        } else {
218            None
219        }
220    }
221}
222impl Index<usize> for Vector {
223    type Output = f64;
224
225    fn index(&self, index: usize) -> &Self::Output {
226        match index {
227            0 => self.x.as_ref().unwrap(),
228            1 => self.y.as_ref().unwrap(),
229            2 => self.z.as_ref().unwrap(),
230            _ => panic!("index must be 0, 1 or 2."),
231        }
232    }
233}
234impl IndexMut<usize> for Vector {
235    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
236        match index {
237            0 => self.x.as_mut().unwrap(),
238            1 => self.y.as_mut().unwrap(),
239            2 => self.z.as_mut().unwrap(),
240            _ => panic!("index must be 0, 1 or 2."),
241        }
242    }
243}
244impl fmt::Display for Vector {
245    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
246        write!(f, "[{:6.3?},{:6.3?},{:6.3?}]", self.x, self.y, self.z)
247    }
248}
249impl From<[f64; 3]> for Vector {
250    fn from(v: [f64; 3]) -> Self {
251        Vector {
252            x: Some(v[0]),
253            y: Some(v[1]),
254            z: Some(v[2]),
255        }
256    }
257}
258impl From<&[f64; 3]> for Vector {
259    fn from(v: &[f64; 3]) -> Self {
260        Vector {
261            x: Some(v[0]),
262            y: Some(v[1]),
263            z: Some(v[2]),
264        }
265    }
266}
267impl From<Vec<f64>> for Vector {
268    fn from(v: Vec<f64>) -> Self {
269        Vector {
270            x: Some(v[0]),
271            y: Some(v[1]),
272            z: Some(v[2]),
273        }
274    }
275}
276impl From<&Vec<f64>> for Vector {
277    fn from(v: &Vec<f64>) -> Self {
278        Vector {
279            x: Some(v[0]),
280            y: Some(v[1]),
281            z: Some(v[2]),
282        }
283    }
284}
285impl From<&[f64]> for Vector {
286    fn from(v: &[f64]) -> Self {
287        Vector {
288            x: Some(v[0]),
289            y: Some(v[1]),
290            z: Some(v[2]),
291        }
292    }
293}
294impl From<Vector> for Option<[f64; 3]> {
295    fn from(v: Vector) -> Self {
296        if let Vector {
297            x: Some(x),
298            y: Some(y),
299            z: Some(z),
300        } = v
301        {
302            Some([x, y, z])
303        } else {
304            None
305        }
306    }
307}
308impl From<&Vector> for Option<[f64; 3]> {
309    fn from(v: &Vector) -> Self {
310        if let Vector {
311            x: Some(x),
312            y: Some(y),
313            z: Some(z),
314        } = v
315        {
316            Some([*x, *y, *z])
317        } else {
318            None
319        }
320    }
321}
322impl From<&Vector> for Option<Vec<f64>> {
323    fn from(v: &Vector) -> Self {
324        if let Vector {
325            x: Some(x),
326            y: Some(y),
327            z: Some(z),
328        } = v
329        {
330            Some(vec![*x, *y, *z])
331        } else {
332            None
333        }
334    }
335}
336impl From<Vector> for Option<Vec<f64>> {
337    fn from(v: Vector) -> Self {
338        if let Vector {
339            x: Some(x),
340            y: Some(y),
341            z: Some(z),
342        } = v
343        {
344            Some(vec![x, y, z])
345        } else {
346            None
347        }
348    }
349}