1use serde::{Deserialize, Serialize};
4use std::ops::{Add, AddAssign, Index, IndexMut, Mul, Sub};
5
6#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
8pub struct Vector3D {
9 pub x: f64,
10 pub y: f64,
11 pub z: f64,
12}
13
14impl Vector3D {
15 pub fn new(x: f64, y: f64, z: f64) -> Self {
16 Self { x, y, z }
17 }
18
19 pub fn zero() -> Self {
20 Self { x: 0.0, y: 0.0, z: 0.0 }
21 }
22
23 pub fn distance(&self, other: &Vector3D) -> f64 {
24 ((self.x - other.x).powi(2) +
25 (self.y - other.y).powi(2) +
26 (self.z - other.z).powi(2)).sqrt()
27 }
28
29 pub fn magnitude(&self) -> f64 {
30 (self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
31 }
32
33 pub fn norm(&self) -> f64 {
34 self.magnitude()
35 }
36
37 pub fn zeros() -> Self {
38 Self { x: 0.0, y: 0.0, z: 0.0 }
39 }
40
41 pub fn dot(&self, other: &Vector3D) -> f64 {
42 self.x * other.x + self.y * other.y + self.z * other.z
43 }
44
45 pub fn iter(&self) -> impl Iterator<Item = f64> {
46 [self.x, self.y, self.z].into_iter()
47 }
48}
49
50impl std::ops::Add for Vector3D {
51 type Output = Vector3D;
52
53 fn add(self, other: Vector3D) -> Vector3D {
54 Vector3D {
55 x: self.x + other.x,
56 y: self.y + other.y,
57 z: self.z + other.z,
58 }
59 }
60}
61
62impl std::ops::Sub for Vector3D {
63 type Output = Vector3D;
64
65 fn sub(self, other: Vector3D) -> Vector3D {
66 Vector3D {
67 x: self.x - other.x,
68 y: self.y - other.y,
69 z: self.z - other.z,
70 }
71 }
72}
73
74impl std::ops::Mul<f64> for Vector3D {
75 type Output = Vector3D;
76
77 fn mul(self, scalar: f64) -> Vector3D {
78 Vector3D {
79 x: self.x * scalar,
80 y: self.y * scalar,
81 z: self.z * scalar,
82 }
83 }
84}
85
86impl std::ops::Mul<Vector3D> for f64 {
87 type Output = Vector3D;
88
89 fn mul(self, vector: Vector3D) -> Vector3D {
90 Vector3D {
91 x: self * vector.x,
92 y: self * vector.y,
93 z: self * vector.z,
94 }
95 }
96}
97
98impl std::ops::Neg for Vector3D {
99 type Output = Vector3D;
100
101 fn neg(self) -> Vector3D {
102 Vector3D {
103 x: -self.x,
104 y: -self.y,
105 z: -self.z,
106 }
107 }
108}
109
110impl std::ops::Div<f64> for Vector3D {
111 type Output = Vector3D;
112
113 fn div(self, scalar: f64) -> Vector3D {
114 Vector3D {
115 x: self.x / scalar,
116 y: self.y / scalar,
117 z: self.z / scalar,
118 }
119 }
120}
121
122impl Index<usize> for Vector3D {
123 type Output = f64;
124
125 fn index(&self, index: usize) -> &Self::Output {
126 match index {
127 0 => &self.x,
128 1 => &self.y,
129 2 => &self.z,
130 _ => panic!("Vector3D index out of bounds: {}", index),
131 }
132 }
133}
134
135impl IndexMut<usize> for Vector3D {
136 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
137 match index {
138 0 => &mut self.x,
139 1 => &mut self.y,
140 2 => &mut self.z,
141 _ => panic!("Vector3D index out of bounds: {}", index),
142 }
143 }
144}
145
146impl AddAssign for Vector3D {
147 fn add_assign(&mut self, other: Vector3D) {
148 self.x += other.x;
149 self.y += other.y;
150 self.z += other.z;
151 }
152}