1use std::ops;
2use pyo3::prelude::*;
3
4#[derive(FromPyObject)]
6enum Vec3OrF64 {
7 Vec3(Vec3),
8 F64(f64)
9}
10
11#[pyclass(from_py_object)]
12#[derive(Debug, Copy, Clone, PartialEq)]
13pub struct Vec3 {
14 #[pyo3(get, set)]
15 pub x: f64,
16 #[pyo3(get, set)]
17 pub y: f64,
18 #[pyo3(get, set)]
19 pub z: f64,
20}
21
22#[pymethods]
23impl Vec3 {
24 #[new]
25 pub fn new(x: f64, y: f64, z: f64) -> Self {
26 Self {
27 x: x,
28 y: y,
29 z: z
30 }
31 }
32
33 #[staticmethod]
34 pub fn cofm1() -> Self {
35 Self {
36 x: 0.0,
37 y: 0.0,
38 z: 0.0
39 }
40 }
41
42 #[staticmethod]
43 pub fn cofm2() -> Self {
44 Self {
45 x: 1.0,
46 y: 0.0,
47 z: 0.0
48 }
49 }
50
51 pub fn set(&mut self, x: f64, y: f64, z: f64) -> () {
52 self.x = x;
53 self.y = y;
54 self.z = z;
55 }
56
57 pub fn unit(&mut self) {
59 let norm = self.length();
60 self.x /= norm;
61 self.y /= norm;
62 self.z /= norm;
63 }
64
65 pub fn norm(&self) -> Self {
67 let norm = self.length();
68 Self {
69 x: self.x / norm,
70 y: self.y / norm,
71 z: self.z / norm
72 }
73 }
74
75 fn __repr__(&self) -> String {
78 format!("Vec3({}, {}, {})", self.x, self.y, self.z)
82 }
83
84 pub fn length(&self) -> f64 {
86 (self.x.powi(2) + self.y.powi(2) + self.z.powi(2)).sqrt()
87 }
88
89 pub fn sqr(&self) -> f64 {
91 self.x.powi(2) + self.y.powi(2) + self.z.powi(2)
92 }
93
94 pub fn dot(&self, other: &Vec3) -> f64 {
96 self.x*other.x + self.y*other.y + self.z*other.z
97 }
98
99 pub fn cross(&self, other: &Vec3) -> Vec3 {
101 let temp_x = self.y*other.z - self.z*other.y;
102 let temp_y = self.z*other.x - self.x*other.z;
103 let temp_z = self.x*other.y - self.y*other.x;
104 Vec3::new(temp_x, temp_y, temp_z)
105 }
106
107 fn __add__(&self, other: Vec3OrF64) -> Self {
109 match other {
110 Vec3OrF64::Vec3(v) => self.clone() + v,
111 Vec3OrF64::F64(f) => self.clone() + f
112 }
113 }
114 fn __radd__(&self, other: Vec3OrF64) -> Self {
115 match other {
116 Vec3OrF64::Vec3(v) => v + self.clone(),
117 Vec3OrF64::F64(f) => f + self.clone()
118 }
119 }
120 fn __sub__(&self, other: Vec3OrF64) -> Self {
121 match other {
122 Vec3OrF64::Vec3(v) => self.clone() - v,
123 Vec3OrF64::F64(f) => self.clone() - f
124 }
125 }
126 fn __rsub__(&self, other: Vec3OrF64) -> Self {
127 match other {
128 Vec3OrF64::Vec3(v) => v - self.clone(),
129 Vec3OrF64::F64(f) => f - self.clone()
130 }
131 }
132 fn __mul__(&self, other: f64) -> Self {
133 self.clone() * other
134 }
135 fn __rmul__(&self, other: f64) -> Self {
136 other * self.clone()
137 }
138 fn __truediv__(&self, other: f64) -> Self {
139 self.clone() / other
140 }
141 fn __rtruediv__(&self, other: f64) -> Self {
142 other / self.clone()
143 }
144 fn __neg__(&self) -> Self {
145 -self.clone()
146 }
147
148}
149
150impl ops::MulAssign<f64> for Vec3 {
152 fn mul_assign(&mut self, rhs: f64) {
153 self.x *= rhs;
154 self.y *= rhs;
155 self.z *= rhs;
156 }
157}
158
159impl ops::DivAssign<f64> for Vec3 {
161 fn div_assign(&mut self, rhs: f64) {
162 self.x /= rhs;
163 self.y /= rhs;
164 self.z /= rhs;
165 }
166}
167
168impl ops::AddAssign<Vec3> for Vec3 {
170 fn add_assign(&mut self, rhs: Vec3) {
171 self.x += rhs.x;
172 self.y += rhs.y;
173 self.z += rhs.z;
174 }
175}
176
177
178impl ops::SubAssign<Vec3> for Vec3 {
180 fn sub_assign(&mut self, rhs: Vec3) {
181 self.x -= rhs.x;
182 self.y -= rhs.y;
183 self.z -= rhs.z;
184 }
185}
186
187impl ops::Add for Vec3 {
189 type Output = Self;
190 fn add(self, other: Self) -> Self {
191 Self {
192 x: self.x + other.x,
193 y: self.y + other.y,
194 z: self.z + other.z,
195 }
196 }
197}
198
199impl ops::Add<f64> for Vec3 {
201 type Output = Self;
202 fn add(self, other: f64) -> Self {
203 Self {
204 x: self.x + other,
205 y: self.y + other,
206 z: self.z + other,
207 }
208 }
209}
210
211impl ops::Add<Vec3> for f64 {
213 type Output = Vec3;
214 fn add(self, other: Vec3) -> Vec3 {
215 Vec3 {
216 x: self + other.x,
217 y: self + other.y,
218 z: self + other.z,
219 }
220 }
221}
222
223impl ops::Sub for Vec3 {
225 type Output = Self;
226 fn sub(self, other: Self) -> Self {
227 Self {
228 x: self.x - other.x,
229 y: self.y - other.y,
230 z: self.z - other.z,
231 }
232 }
233}
234
235impl ops::Sub<f64> for Vec3 {
237 type Output = Self;
238 fn sub(self, other: f64) -> Self {
239 Self {
240 x: self.x - other,
241 y: self.y - other,
242 z: self.z - other,
243 }
244 }
245}
246
247impl ops::Sub<Vec3> for f64 {
249 type Output = Vec3;
250 fn sub(self, other: Vec3) -> Vec3 {
251 Vec3 {
252 x: self - other.x,
253 y: self - other.y,
254 z: self - other.z,
255 }
256 }
257}
258
259impl ops::Mul<f64> for Vec3 {
261 type Output = Self;
262
263 fn mul(self, rhs: f64) -> Self {
264 Self{
265 x: self.x * rhs,
266 y: self.y * rhs,
267 z: self.z * rhs,
268 }
269 }
270}
271
272impl ops::Mul<Vec3> for f64 {
274 type Output = Vec3;
275
276 fn mul(self, rhs: Vec3) -> Vec3 {
277 Vec3{
278 x: self * rhs.x,
279 y: self * rhs.y,
280 z: self * rhs.z,
281 }
282 }
283}
284
285impl ops::Div<f64> for Vec3 {
287 type Output = Self;
288
289 fn div(self, rhs: f64) -> Self {
290 Self{
291 x: self.x / rhs,
292 y: self.y / rhs,
293 z: self.z / rhs,
294 }
295 }
296}
297
298impl ops::Div<Vec3> for f64 {
300 type Output = Vec3;
301
302 fn div(self, rhs: Vec3) -> Vec3 {
303 Vec3{
304 x: self / rhs.x,
305 y: self / rhs.y,
306 z: self / rhs.z,
307 }
308 }
309}
310
311impl ops::Neg for Vec3 {
313 type Output = Self;
314
315 fn neg(self) -> Self {
316 Vec3{
317 x: -self.x,
318 y: -self.y,
319 z: -self.z,
320 }
321 }
322}
323