sath/vector/
d2.rs

1use crate::{Complex, Float, Vector3};
2use std::{cmp::Ordering, ops::Mul};
3
4/// Single precession Vector2.
5pub type Vector2f = Vector2<f32>;
6/// Double precession Vector2.
7pub type Vector2d = Vector2<f64>;
8
9/// 2 Dimensional vector.
10#[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    /// Converts a vector to a complex number with `real` = `x`, `imag` = `y`.
28    #[inline]
29    pub const fn to_complex(self) -> Complex<F> {
30        Complex {
31            real: self.x,
32            imag: self.y,
33        }
34    }
35
36    /// Converts a complex number to a vector with `x` = `real`, `y` = `imag`.
37    #[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    /// Extends the vector with `z` component to create a [`Vector3`].
46    #[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    /// Rotates angle around origin by some angle `angle` in radians counter-clockwise.
56    #[inline]
57    pub fn rotate_by(&mut self, angle: F) {
58        *self = *self * Complex::from_angle(angle)
59    }
60
61    /// Returns a rotated copy of a vector. See [`Self::rotate_by`].
62    #[inline]
63    pub fn rotated_by(self, angle: F) -> Self {
64        self * Complex::from_angle(angle)
65    }
66
67    /// Rotates angle around origin by some angle `angle` in radians clockwise.
68    #[inline]
69    pub fn rotate_by_clockwise(&mut self, angle: F) {
70        *self = *self * Complex::from_angle(angle).conjugate()
71    }
72
73    /// Returns a rotated copy of a vector. See [`Self::rotate_by_clockwise`].
74    #[inline]
75    pub fn rotated_by_clockwise(self, angle: F) -> Self {
76        self * Complex::from_angle(angle).conjugate()
77    }
78
79    /// Returns maximum element of the vector.
80    #[inline]
81    pub fn max_element(&self) -> F {
82        self.x.max(self.y)
83    }
84
85    /// Returns minumum element of the vector.
86    #[inline]
87    pub fn min_element(&self) -> F {
88        self.x.min(self.y)
89    }
90
91    /// Returns index of the maximum element.
92    /// Index is in `0..=1` range.
93    #[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    /// Returns index of the minumum element.
103    /// Index is in `0..=1` range.
104    #[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]);