1use std::fmt::{Debug, Error, Formatter};
6use std::ops::*;
7use crate::prelude::*;
8use crate::prelude::coordinates::*;
9use crate::matrix::{Matrix2, Matrix3, Matrix4};
10use crate::point::Point2;
11use crate::{impl_vector, impl_debug_vector};
12
13pub mod consts {
15 use super::*;
16
17 pub const EX_2: Vector2 = Vector2 { x: 1., y: 0. };
19 pub const N_EX_2: Vector2 = Vector2 { x: -1., y: 0. };
21 pub const EY_2: Vector2 = Vector2 { x: 0., y: 1. };
23 pub const N_EY_2: Vector2 = Vector2 { x: 0., y: -1. };
25 pub const ZEROS_2: Vector2 = Vector2 { x: 0., y: 0. };
27 pub const ONES_2: Vector2 = Vector2 { x: 1., y: 1. };
29
30
31 pub const EX_3: Vector3 = Vector3 { x: 1., y: 0., z: 0. };
33 pub const N_EX_3: Vector3 = Vector3 { x: -1., y: 0., z: 0. };
35 pub const EY_3: Vector3 = Vector3 { x: 0., y: 1., z: 0. };
37 pub const N_EY_3: Vector3 = Vector3 { x: 0., y: -1., z: 0. };
39 pub const EZ_3: Vector3 = Vector3 { x: 0., y: 0., z: 1. };
41 pub const N_EZ_3: Vector3 = Vector3 { x: 0., y: 0., z: -1. };
43 pub const ZEROS_3: Vector3 = Vector3 { x: 0., y: 0., z: 0. };
45 pub const ONES_3: Vector3 = Vector3 { x: 1., y: 1., z: 1. };
47
48
49 pub const EX_4: Vector4 = Vector4 { x: 1., y: 0., z: 0., w: 0. };
51 pub const N_EX_4: Vector4 = Vector4 { x: -1., y: 0., z: 0., w: 0. };
53 pub const EY_4: Vector4 = Vector4 { x: 0., y: 1., z: 0., w: 0. };
55 pub const N_EY_4: Vector4 = Vector4 { x: 0., y: -1., z: 0., w: 0. };
57 pub const EZ_4: Vector4 = Vector4 { x: 0., y: 0., z: 1., w: 0. };
59 pub const N_EZ_4: Vector4 = Vector4 { x: 0., y: 0., z: -1., w: 0. };
61 pub const EW_4: Vector4 = Vector4 { x: 0., y: 0., z: 0., w: 1. };
63 pub const N_EW_4: Vector4 = Vector4 { x: 0., y: 0., z: 0., w: -1. };
65 pub const ZEROS_4: Vector4 = Vector4 { x: 0., y: 0., z: 0., w: 0. };
67 pub const ONES_4: Vector4 = Vector4 { x: 1., y: 1., z: 1., w: 1. };
69}
70
71#[derive(Copy, Clone)]
73pub struct Vector2 {
74 pub x: f64,
75 pub y: f64,
76}
77
78#[derive(Copy, Clone)]
80pub struct Vector3 {
81 pub x: f64,
82 pub y: f64,
83 pub z: f64,
84}
85
86#[derive(Copy, Clone)]
88pub struct Vector4 {
89 pub x: f64,
90 pub y: f64,
91 pub z: f64,
92 pub w: f64,
93}
94
95#[derive(Copy, Clone)]
97pub struct Vector6 {
98 pub x: f64,
99 pub y: f64,
100 pub z: f64,
101 pub u: f64,
102 pub v: f64,
103 pub w: f64,
104}
105
106impl From<[f64; 2]> for Vector2 {
107 fn from(array: [f64; 2]) -> Self {
108 vec2(array[0], array[1])
109 }
110}
111
112impl From<[f64; 3]> for Vector3 {
113 fn from(array: [f64; 3]) -> Self {
114 vec3(array[0], array[1], array[2])
115 }
116}
117
118impl From<[f64; 4]> for Vector4 {
119 fn from(array: [f64; 4]) -> Self {
120 vec4(array[0], array[1], array[2], array[3])
121 }
122}
123
124impl From<[f64; 6]> for Vector6 {
125 fn from(array: [f64; 6]) -> Self {
126 vec6(array[0], array[1], array[2], array[3], array[4], array[5])
127 }
128}
129
130impl From<Point2> for Vector4 {
131 fn from(point: Point2) -> Self {
132 vec4(point.position.x, point.position.y, point.speed.x, point.speed.y)
133 }
134}
135
136impl_vector!(Vector2 {x, y}, 2, vec2);
137impl_vector!(Vector3 {x, y, z}, 3, vec3);
138impl_vector!(Vector4 {x, y, z, w}, 4, vec4);
139impl_vector!(Vector6 {x, y, z, u, v, w}, 6, vec6);
140
141impl_debug_vector!(Vector2 {x, y});
142impl_debug_vector!(Vector3 {x, y, z});
143impl_debug_vector!(Vector4 {x, y, z, w});
144impl_debug_vector!(Vector6 {x, y, z, u, v, w});
145
146impl MulAssign<Matrix2> for Vector2 {
147 fn mul_assign(&mut self, rhs: Matrix2) {
148 let x = self.x;
149 let y = self.y;
150 self.x = rhs.xx * x + rhs.xy * y;
151 self.y = rhs.yx * x + rhs.yy * y;
152 }
153}
154
155impl MulAssign<Matrix3> for Vector3 {
156 fn mul_assign(&mut self, rhs: Matrix3) {
157 let x = self.x;
158 let y = self.y;
159 let z = self.z;
160 self.x = rhs.xx * x + rhs.xy * y + rhs.xz * z;
161 self.y = rhs.yx * x + rhs.yy * y + rhs.yz * z;
162 self.z = rhs.zx * x + rhs.zy * y + rhs.zz * z;
163 }
164}
165
166impl MulAssign<Matrix3> for Vector2 {
167 fn mul_assign(&mut self, rhs: Matrix3) {
168 let x = self.x;
169 let y = self.y;
170 self.x = rhs.xx * x + rhs.xy * y + rhs.xz;
171 self.y = rhs.yx * x + rhs.yy * y + rhs.yz;
172 }
173}
174
175impl MulAssign<Matrix4> for Vector4 {
176 fn mul_assign(&mut self, rhs: Matrix4) {
177 let x = self.x;
178 let y = self.y;
179 let z = self.z;
180 let w = self.w;
181 self.x = rhs.xx * x + rhs.xy * y + rhs.xz * z + rhs.xw * w;
182 self.y = rhs.yx * x + rhs.yy * y + rhs.yz * z + rhs.yw * w;
183 self.z = rhs.zx * x + rhs.zy * y + rhs.zz * z + rhs.zw * w;
184 self.w = rhs.wx * x + rhs.wy * y + rhs.wz * z + rhs.ww * w;
185 }
186}
187
188impl MulAssign<Matrix4> for Vector3 {
189 fn mul_assign(&mut self, rhs: Matrix4) {
190 let x = self.x;
191 let y = self.y;
192 let z = self.z;
193 self.x = rhs.xx * x + rhs.xy * y + rhs.xz * z + rhs.xw;
194 self.y = rhs.yx * x + rhs.yy * y + rhs.yz * z + rhs.yw;
195 self.z = rhs.zx * x + rhs.zy * y + rhs.zz * z + rhs.zw;
196 }
197}
198
199impl Angle for Vector2 {
200 fn area(&self, rhs: &Self) -> f64 {
201 self.x * rhs.y - self.y * rhs.x
202 }
203}
204
205impl Angle for Vector3 {
206 fn area(&self, rhs: &Self) -> f64 {
207 self.cross(rhs).magnitude()
208 }
209}
210
211impl Cross for Vector3 {
212 fn set_cross(&mut self, rhs: &Self) -> &mut Self {
213 let x = self.x;
214 let y = self.y;
215 let z = self.z;
216 self.x = y * rhs.z - z * rhs.y;
217 self.y = z * rhs.x - x * rhs.z;
218 self.z = x * rhs.y - y * rhs.x;
219 self
220 }
221}
222
223impl coordinates::Polar for Vector2 {
224 #[inline]
225 fn from_polar(rho: f64, phi: f64) -> Self {
226 Vector2 { x: rho * phi.cos(), y: rho * phi.sin() }
227 }
228
229 #[inline]
230 fn set_polar(&mut self, rho: f64, phi: f64) -> &mut Self {
231 self.x = rho * phi.cos();
232 self.y = rho * phi.sin();
233 self
234 }
235
236 #[inline]
237 fn unit_rho(ang: f64) -> Self {
238 Vector2 { x: ang.cos(), y: ang.sin() }
239 }
240
241 #[inline]
242 fn unit_phi(ang: f64) -> Self {
243 Vector2 { x: -ang.sin(), y: ang.cos() }
244 }
245
246 #[inline]
247 fn rho(&self) -> f64 {
248 self.magnitude()
249 }
250
251 #[inline]
252 fn phi(&self) -> f64 {
253 (self.y).atan2(self.x)
254 }
255
256 #[inline]
257 fn set_rho(&mut self, rho: f64) -> &mut Self {
258 self.set_polar(rho, self.phi())
259 }
260
261 #[inline]
262 fn set_phi(&mut self, phi: f64) -> &mut Self {
263 self.set_polar(self.rho(), phi)
264 }
265}
266
267impl coordinates::Polar for Vector3 {
268 #[inline]
269 fn from_polar(rho: f64, phi: f64) -> Self {
270 Vector3 { x: rho * phi.cos(), y: rho * phi.sin(), z: 0. }
271 }
272
273 #[inline]
274 fn set_polar(&mut self, rho: f64, phi: f64) -> &mut Self {
275 self.x = rho * phi.cos();
276 self.y = rho * phi.sin();
277 self
278 }
279
280 #[inline]
281 fn unit_rho(phi: f64) -> Self {
282 Vector3 { x: phi.cos(), y: phi.sin(), z: 0. }
283 }
284
285 #[inline]
286 fn unit_phi(phi: f64) -> Self {
287 Vector3 { x: -phi.sin(), y: phi.cos(), z: 0. }
288 }
289
290 #[inline]
291 fn rho(&self) -> f64 {
292 (self.x * self.x + self.y * self.y).sqrt()
293 }
294
295 #[inline]
296 fn phi(&self) -> f64 {
297 (self.y).atan2(self.x)
298 }
299
300 #[inline]
301 fn set_rho(&mut self, rho: f64) -> &mut Self {
302 self.set_polar(rho, self.phi())
303 }
304
305 #[inline]
306 fn set_phi(&mut self, phi: f64) -> &mut Self {
307 self.set_polar(self.rho(), phi)
308 }
309}
310
311impl coordinates::Cylindrical for Vector3 {
312 #[inline]
313 fn from_cylindrical(rho: f64, phi: f64, z: f64) -> Self {
314 Vector3 { x: rho * phi.cos(), y: rho * phi.sin(), z }
315 }
316
317 #[inline]
318 fn set_cylindrical(&mut self, rho: f64, phi: f64, z: f64) -> &mut Self {
319 self.x = rho * phi.cos();
320 self.y = rho * phi.sin();
321 self.z = z;
322 self
323 }
324}
325
326impl coordinates::Spherical for Vector3 {
327 #[inline]
328 fn from_spherical(radius: f64, phi: f64, theta: f64) -> Self {
329 let s = theta.sin();
330 Vector3 {
331 x: radius * s * phi.cos(),
332 y: radius * s * phi.sin(),
333 z: radius * theta.cos(),
334 }
335 }
336
337 #[inline]
338 fn set_spherical(&mut self, radius: f64, phi: f64, theta: f64) -> &mut Self {
339 let s = theta.sin();
340 self.x = radius * s * phi.cos();
341 self.y = radius * s * phi.sin();
342 self.z = radius * theta.cos();
343 self
344 }
345
346 #[inline]
347 fn unit_radius(phi: f64, theta: f64) -> Self {
348 let s = theta.sin();
349 Vector3 {
350 x: s * phi.cos(),
351 y: s * phi.sin(),
352 z: theta.cos(),
353 }
354 }
355
356 #[inline]
357 fn unit_theta(phi: f64, theta: f64) -> Self {
358 let c = theta.cos();
359 Vector3 {
360 x: c * phi.cos(),
361 y: c * phi.sin(),
362 z: -theta.sin(),
363 }
364 }
365
366 #[inline]
367 fn theta(&self) -> f64 {
368 (self.x * self.x + self.y * self.y).atan2(self.z)
369 }
370
371 #[inline]
372 fn set_theta(&mut self, theta: f64) -> &mut Self {
373 self.set_spherical(self.magnitude(), self.phi(), theta)
374 }
375}
376
377impl coordinates::Homogeneous<Vector3> for Vector2 {
378 fn from_homogeneous(vector: &Vector3) -> Self {
379 vec2(vector.x / vector.z, vector.y / vector.z)
380 }
381
382 fn to_homogeneous(&self) -> Vector3 {
383 vec3(self.x, self.y, 1.)
384 }
385}
386
387impl coordinates::Homogeneous<Vector4> for Vector3 {
388 fn from_homogeneous(vector: &Vector4) -> Self {
389 vec3(vector.x / vector.w, vector.y / vector.w, vector.z / vector.w)
390 }
391
392 fn to_homogeneous(&self) -> Vector4 {
393 vec4(self.x, self.y, self.z, 1.)
394 }
395}
396
397impl transforms::Rotation3 for Vector3 {
398 fn set_rotation(&mut self, angle: f64, axis: &Vector3) -> &mut Self {
399 let c = angle.cos();
400 let s = angle.sin();
401 let k = 1. - c;
402 let x = self.x;
403 let y = self.y;
404 let z = self.z;
405 let ux = axis.x;
406 let uy = axis.y;
407 let uz = axis.z;
408
409 let k_uxy = k * ux * uy;
410 let k_uxz = k * ux * uz;
411 let k_uyz = k * uy * uz;
412
413 self.x = (k * ux * ux + c) * x + (k_uxy - uz * s) * y + (k_uxz + uy * s) * z;
414 self.y = (k_uxy + uz * s) * x + (k * uy * uy + c) * y + (k_uyz - ux * s) * z;
415 self.z = (k_uxz - uy * s) * x + (k_uyz + ux * s) * y + (k * uz * uz + c) * z;
416 self
417 }
418
419 fn set_rotation_x(&mut self, angle: f64) -> &mut Self {
420 let c = angle.cos();
421 let s = angle.sin();
422 let y = self.y;
423 let z = self.z;
424
425 self.y = y * c - z * s;
426 self.z = y * s + z * c;
427 self
428 }
429
430 fn set_rotation_y(&mut self, angle: f64) -> &mut Self {
431 let c = angle.cos();
432 let s = angle.sin();
433 let x = self.x;
434 let z = self.z;
435
436 self.x = x * c + z * s;
437 self.z = z * c - x * s;
438 self
439 }
440
441 fn set_rotation_z(&mut self, angle: f64) -> &mut Self {
442 let c = angle.cos();
443 let s = angle.sin();
444 let x = self.x;
445 let y = self.y;
446
447 self.x = x * c - y * s;
448 self.y = x * s + y * c;
449 self
450 }
451}
452
453impl Array<[f64; 2]> for Vector2 {
454 #[inline]
455 fn to_array(&self) -> [f64; 2] {
456 [self.x, self.y]
457 }
458
459 #[inline]
460 fn set_array(&mut self, array: &[f64; 2]) -> &mut Self {
461 self.x = array[0];
462 self.y = array[1];
463 self
464 }
465}
466
467impl Array<[f64; 3]> for Vector3 {
468 #[inline]
469 fn to_array(&self) -> [f64; 3] {
470 [self.x, self.y, self.z]
471 }
472
473 #[inline]
474 fn set_array(&mut self, array: &[f64; 3]) -> &mut Self {
475 self.x = array[0];
476 self.y = array[1];
477 self.z = array[2];
478 self
479 }
480}
481
482impl Array<[f64; 4]> for Vector4 {
483 #[inline]
484 fn to_array(&self) -> [f64; 4] {
485 [self.x, self.y, self.z, self.w]
486 }
487
488 #[inline]
489 fn set_array(&mut self, array: &[f64; 4]) -> &mut Self {
490 self.x = array[0];
491 self.y = array[1];
492 self.z = array[2];
493 self.w = array[3];
494 self
495 }
496}
497
498impl Array<[f64; 6]> for Vector6 {
499 #[inline]
500 fn to_array(&self) -> [f64; 6] {
501 [self.x, self.y, self.z, self.u, self.v, self.w]
502 }
503
504 #[inline]
505 fn set_array(&mut self, array: &[f64; 6]) -> &mut Self {
506 self.x = array[0];
507 self.y = array[1];
508 self.z = array[2];
509 self.u = array[3];
510 self.v = array[4];
511 self.w = array[5];
512 self
513 }
514}
515
516impl Split<Vector2> for Vector4 {
517 fn split(&self) -> [Vector2; 2] {
518 [self.upper(), self.lower()]
519 }
520
521 fn concat(lhs: &Vector2, rhs: &Vector2) -> Self {
522 vec4(lhs.x, lhs.y, rhs.x, rhs.y)
523 }
524
525 #[inline]
526 fn upper(&self) -> Vector2 {
527 vec2(self.x, self.y)
528 }
529
530 #[inline]
531 fn lower(&self) -> Vector2 {
532 vec2(self.z, self.w)
533 }
534
535 #[inline]
536 fn set_upper(&mut self, vector: &Vector2) -> &mut Self {
537 self.x = vector.x;
538 self.y = vector.y;
539 self
540 }
541
542 #[inline]
543 fn set_lower(&mut self, vector: &Vector2) -> &mut Self {
544 self.z = vector.x;
545 self.w = vector.y;
546 self
547 }
548}
549
550impl Split<Vector3> for Vector6 {
551 fn split(&self) -> [Vector3; 2] {
552 [self.upper(), self.lower()]
553 }
554
555 fn concat(lhs: &Vector3, rhs: &Vector3) -> Self {
556 vec6(lhs.x, lhs.y, lhs.z, rhs.x, rhs.y, rhs.z)
557 }
558
559 #[inline]
560 fn upper(&self) -> Vector3 {
561 vec3(self.x, self.y, self.z)
562 }
563
564 #[inline]
565 fn lower(&self) -> Vector3 {
566 vec3(self.u, self.v, self.w)
567 }
568
569 #[inline]
570 fn set_upper(&mut self, vector: &Vector3) -> &mut Self {
571 self.x = vector.x;
572 self.y = vector.y;
573 self.z = vector.z;
574 self
575 }
576
577 #[inline]
578 fn set_lower(&mut self, vector: &Vector3) -> &mut Self {
579 self.u = vector.x;
580 self.v = vector.y;
581 self.w = vector.z;
582 self
583 }
584}
585
586#[cfg(test)]
587mod tests {
588 mod vector3 {
589 use crate::assert_near;
590 use crate::prelude::*;
591 use crate::prelude::transforms::Rotation3;
592 use crate::vector;
593 use crate::prelude::coordinates::*;
594 use crate::vector::vec3;
595
596 #[test]
597 fn new() {
598 let u = vec3(1., 2., 3.);
599 assert_eq!(u.x, 1.);
600 assert_eq!(u.y, 2.);
601 assert_eq!(u.z, 3.);
602 }
603
604 #[test]
605 fn magnitude() {
606 let sqrt_2 = std::f64::consts::SQRT_2;
607 let zero = vector::consts::ZEROS_3;
608 let u = vec3(1., 1., 0.);
609 assert_eq!(u.magnitude2(), 2.);
610 assert_eq!(u.magnitude(), sqrt_2);
611 assert_eq!(u.distance2(&zero), 2.);
612 assert_eq!(u.distance(&zero), sqrt_2);
613 }
614
615 #[test]
616 fn partial_eq() {
617 let u = vec3(-4., 0., 1.);
618 let v = vec3(-2., 0., 1.);
619 assert_eq!(u, u);
620 assert_ne!(u, v);
621 }
622
623 #[test]
624 fn polar_coordinates() {
625 let u = vector::consts::ONES_3;
626 assert_eq!(u.rho(), std::f64::consts::SQRT_2);
627 assert_eq!(u.phi(), std::f64::consts::FRAC_PI_4);
628 }
629
630 #[test]
631 fn normalized() {
632 let mut u = vec3(1., 1., 0.);
633 let tol = 10. * std::f64::EPSILON;
634 let inv_sqrt2 = std::f64::consts::FRAC_1_SQRT_2;
635 u.set_normalized();
636 assert_near!(u.magnitude2(), 1f64, tol);
637 assert_near!(u.x, inv_sqrt2, tol);
638 assert_near!(u.y, inv_sqrt2, tol);
639 assert_near!(u.z, 0., tol);
640 }
641
642 #[test]
643 fn fmt() {
644 let u = vec3(1., 2., 3.);
645 let formatted = format!("{:?}", u);
646 assert_eq!(formatted.as_str(), "( 1.000 2.000 3.000 )");
647 }
648
649 #[test]
650 fn distance() {
651 let u = vec3(1., 1., 0.);
652 let v = vector::consts::ZEROS_3;
653 assert_eq!(u.distance2(&v), 2f64);
654 }
655
656 #[test]
657 fn arithmetic() {
658 let mut u = vec3(-4., 1., 1.);
659 let v = vec3(3., 2., -1.);
660
661 assert_eq!(u + v, vec3(-1., 3., 0.));
662 assert_eq!(u - v, vec3(-7., -1., 2.));
663 assert_eq!(u * 2., vec3(-8., 2., 2.));
664 assert_eq!(u / 4., vec3(-1., 0.25, 0.25));
665
666 u += v;
667 assert_eq!(u, vec3(-1., 3., 0.));
668 }
669
670 #[test]
671 fn angles() {
672 let angle = std::f64::consts::FRAC_PI_4;
673 let u = vector::consts::EX_3;
674 let mut v = u;
675
676 assert_eq!(u.angle(&v), 0.);
677 v.set_rotation_z(angle);
678 assert_near!(u.angle(&v), angle, std::f64::EPSILON);
679 assert_near!(v.angle(&u), angle, std::f64::EPSILON);
680 v.set_rotation_z(angle);
681 assert_near!(u.angle(&v), 2. * angle, 10. * std::f64::EPSILON);
682 v.set_rotation_z(angle);
683 assert_near!(u.angle(&v), 3. * angle, 10. * std::f64::EPSILON);
684 v.set_rotation_z(angle);
685 assert_eq!(u.angle(&v), 4. * angle);
686 }
687
688 #[test]
689 fn rotations_xyz() {
690 let angle = std::f64::consts::FRAC_PI_2;
691 let mut u = vector::consts::EX_3;
692 let mut v = vector::consts::EY_3;
693 let mut w = vector::consts::EZ_3;
694
695 u.set_rotation_z(angle);
696 assert_near!(u.distance2(&vector::consts::EY_3), 0., std::f64::EPSILON);
697
698 v.set_rotation_x(angle);
699 assert_near!(v.distance2(&vector::consts::EZ_3), 0., std::f64::EPSILON);
700
701 w.set_rotation_y(angle);
702 assert_near!(w.distance2(&vector::consts::EX_3), 0., std::f64::EPSILON);
703 }
704
705 #[test]
706 fn rotations() {
707 let angle = std::f64::consts::FRAC_PI_2;
708 let mut u = vector::consts::EX_3;
709 let mut v = vector::consts::EY_3;
710 let mut w = vector::consts::EZ_3;
711
712 let mut axis = vector::consts::EZ_3;
713 u.set_rotation(angle, &axis);
714 assert_near!(u.distance2(&vector::consts::EY_3), 0., std::f64::EPSILON);
715
716 axis = vector::consts::EX_3;
717 v.set_rotation(angle, &axis);
718 assert_near!(v.distance2(&vector::consts::EZ_3), 0., std::f64::EPSILON);
719
720 axis = vector::consts::EY_3;
721 w.set_rotation(angle, &axis);
722 assert_near!(w.distance2(&vector::consts::EX_3), 0., std::f64::EPSILON);
723 }
724 }
725}