1use crate::{Complex, Float, Vector3};
2use std::{cmp::Ordering, ops::Mul};
3
4pub type Vector2f = Vector2<f32>;
6pub type Vector2d = Vector2<f64>;
8
9#[derive(Default, Debug, Clone, Copy, PartialEq, PartialOrd)]
11#[repr(C)]
12pub struct Vector2<F: Float> {
13 pub x: F,
14 pub y: F,
15}
16
17impl<F: Float> Vector2<F> {
18 pub const ZERO: Self = Self::new(F::ZERO, F::ZERO);
19 pub const ONE: Self = Self::new(F::ONE, F::ONE);
20
21 pub const X: Self = Self::new(F::ONE, F::ZERO);
22 pub const Y: Self = Self::new(F::ZERO, F::ONE);
23 pub const XY: Self = Self::new(F::ONE, F::ONE);
24}
25
26impl<F: Float> Vector2<F> {
27 #[inline]
29 pub const fn to_complex(self) -> Complex<F> {
30 Complex {
31 real: self.x,
32 imag: self.y,
33 }
34 }
35
36 #[inline]
38 pub const fn from_complex(complex: Complex<F>) -> Self {
39 Self {
40 x: complex.real,
41 y: complex.imag,
42 }
43 }
44
45 #[inline]
47 pub const fn extend(self, z: F) -> Vector3<F> {
48 Vector3 {
49 x: self.x,
50 y: self.y,
51 z,
52 }
53 }
54
55 #[inline]
57 pub fn rotate_by(&mut self, angle: F) {
58 *self = *self * Complex::from_angle(angle)
59 }
60
61 #[inline]
63 pub fn rotated_by(self, angle: F) -> Self {
64 self * Complex::from_angle(angle)
65 }
66
67 #[inline]
69 pub fn rotate_by_clockwise(&mut self, angle: F) {
70 *self = *self * Complex::from_angle(angle).conjugate()
71 }
72
73 #[inline]
75 pub fn rotated_by_clockwise(self, angle: F) -> Self {
76 self * Complex::from_angle(angle).conjugate()
77 }
78
79 #[inline]
81 pub fn max_element(&self) -> F {
82 self.x.max(self.y)
83 }
84
85 #[inline]
87 pub fn min_element(&self) -> F {
88 self.x.min(self.y)
89 }
90
91 #[inline]
94 pub fn max_index(&self) -> usize {
95 [(self.x, 0), (self.y, 1)]
96 .iter()
97 .max_by(|(a, _), (b, _)| a.partial_cmp(b).unwrap_or(Ordering::Equal))
98 .map(|(_, i)| *i)
99 .unwrap()
100 }
101
102 #[inline]
105 pub fn min_index(&self) -> usize {
106 [(self.x, 0), (self.y, 1)]
107 .iter()
108 .min_by(|(a, _), (b, _)| a.partial_cmp(b).unwrap_or(Ordering::Equal))
109 .map(|(_, i)| *i)
110 .unwrap()
111 }
112
113 #[inline]
114 pub fn reflect(&self, axis: Self) -> Self {
115 self.projected_onto(axis) * F::TWO - *self
116 }
117}
118
119impl<F: Float> From<Complex<F>> for Vector2<F> {
120 #[inline]
121 fn from(val: Complex<F>) -> Self {
122 Self {
123 x: val.real,
124 y: val.imag,
125 }
126 }
127}
128
129impl<F: Float> Mul<Complex<F>> for Vector2<F> {
130 type Output = Self;
131
132 #[inline]
133 fn mul(self, rhs: Complex<F>) -> Self::Output {
134 Self {
135 x: self.x * rhs.real - self.y * rhs.imag,
136 y: self.x * rhs.imag + self.y * rhs.real,
137 }
138 }
139}
140
141unsafe impl<F: Float> bytemuck::Pod for Vector2<F> {}
142unsafe impl<F: Float> bytemuck::Zeroable for Vector2<F> {}
143
144crate::__impl_vec_ops!(Vector2, 1, x, y);
145crate::__impl_planar_ops!(Vector2, [x, 0, F], [y, 1, F]);