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}