gee/
vector.rs

1use crate::{Angle, Cardinal, Direction, Point, Size, Transform};
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4use std::ops::{
5    Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
6};
7
8#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
9#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10#[repr(C)]
11pub struct Vector<T = f32> {
12    pub dx: T,
13    pub dy: T,
14}
15
16impl<T: en::Num> Vector<T> {
17    pub fn new(dx: T, dy: T) -> Self {
18        Self { dx, dy }
19    }
20
21    pub fn uniform(d: T) -> Self {
22        Self::new(d, d)
23    }
24
25    pub fn from_dx(dx: T) -> Self {
26        Self { dx, dy: T::zero() }
27    }
28
29    pub fn from_dy(dy: T) -> Self {
30        Self { dx: T::zero(), dy }
31    }
32
33    pub fn zero() -> Self {
34        Self::uniform(T::zero())
35    }
36
37    pub fn one() -> Self {
38        Self::uniform(T::one())
39    }
40
41    pub fn from_array([dx, dy]: [T; 2]) -> Self {
42        Self::new(dx, dy)
43    }
44
45    pub fn from_tuple((dx, dy): (T, T)) -> Self {
46        Self::new(dx, dy)
47    }
48
49    pub fn with_dx(self, dx: T) -> Self {
50        Self::new(dx, self.dy)
51    }
52
53    pub fn with_dy(self, dy: T) -> Self {
54        Self::new(self.dx, dy)
55    }
56
57    pub fn dot_product(self, rhs: Self) -> T {
58        self.dx * rhs.dx + self.dy * rhs.dy
59    }
60
61    pub fn magnitude_squared(self) -> T {
62        self.dot_product(self)
63    }
64
65    pub fn magnitude(self) -> T
66    where
67        T: en::Float,
68    {
69        self.magnitude_squared().sqrt()
70    }
71
72    pub fn normalize(self) -> Self
73    where
74        T: en::Float,
75    {
76        self / self.magnitude()
77    }
78
79    pub fn angle(self) -> Angle<T>
80    where
81        T: en::Float,
82    {
83        Angle::from_xy(self.dx, self.dy)
84    }
85
86    pub fn scaled(self, rhs: Size<T>) -> Self {
87        Self::new(self.dx * rhs.width(), self.dy * rhs.height())
88    }
89
90    pub fn perpendicular(self) -> Self
91    where
92        T: Neg<Output = T>,
93    {
94        Self::new(-self.dy, self.dx)
95    }
96
97    pub fn yx(self) -> Self {
98        Self::new(self.dy, self.dx)
99    }
100
101    pub fn transform(&self, transform: Transform<T>) -> Self {
102        Self::new(
103            self.dx * transform.m11 + self.dy * transform.m21 + transform.m31,
104            self.dx * transform.m12 + self.dy * transform.m22 + transform.m32,
105        )
106    }
107
108    pub fn map<U: en::Num>(&self, mut f: impl FnMut(T) -> U) -> Vector<U> {
109        Vector::new(f(self.dx), f(self.dy))
110    }
111
112    pub fn map_dx(&self, mut f: impl FnMut(T) -> T) -> Self {
113        self.with_dx(f(self.dx))
114    }
115
116    pub fn map_dy(&self, mut f: impl FnMut(T) -> T) -> Self {
117        self.with_dy(f(self.dy))
118    }
119
120    impl_casts_and_cast!(Vector);
121
122    pub fn to_array(self) -> [T; 2] {
123        [self.dx, self.dy]
124    }
125
126    pub fn to_tuple(self) -> (T, T) {
127        (self.dx, self.dy)
128    }
129
130    pub fn to_point(self) -> Point<T> {
131        Point::zero() + self
132    }
133
134    pub fn to_size(self) -> Size<T> {
135        self.into()
136    }
137}
138
139impl<T: en::Num> From<Size<T>> for Vector<T> {
140    fn from(size: Size<T>) -> Self {
141        Self::new(size.width(), size.height())
142    }
143}
144
145impl<T: en::Num> Add for Vector<T> {
146    type Output = Self;
147    fn add(self, rhs: Self) -> Self::Output {
148        Self::new(self.dx + rhs.dx, self.dy + rhs.dy)
149    }
150}
151
152impl<T: en::Num> AddAssign for Vector<T> {
153    fn add_assign(&mut self, rhs: Self) {
154        *self = *self + rhs
155    }
156}
157
158impl<T: en::Num> Sub for Vector<T> {
159    type Output = Self;
160    fn sub(self, rhs: Self) -> Self::Output {
161        Self::new(self.dx - rhs.dx, self.dy - rhs.dy)
162    }
163}
164
165impl<T: en::Num> SubAssign for Vector<T> {
166    fn sub_assign(&mut self, rhs: Self) {
167        *self = *self - rhs
168    }
169}
170
171impl<T: en::Num> Mul for Vector<T> {
172    type Output = Self;
173
174    fn mul(self, rhs: Self) -> Self::Output {
175        Self::new(self.dx * rhs.dx, self.dy * rhs.dy)
176    }
177}
178
179impl<T: en::Num> MulAssign for Vector<T> {
180    fn mul_assign(&mut self, rhs: Self) {
181        *self = *self * rhs
182    }
183}
184
185impl<T: en::Num> Mul<T> for Vector<T> {
186    type Output = Self;
187    fn mul(self, rhs: T) -> Self::Output {
188        self.map(move |x| x * rhs)
189    }
190}
191
192impl<T: en::Num> MulAssign<T> for Vector<T> {
193    fn mul_assign(&mut self, rhs: T) {
194        *self = *self * rhs
195    }
196}
197
198impl<T: en::Num> Div for Vector<T> {
199    type Output = Self;
200
201    fn div(self, rhs: Self) -> Self::Output {
202        Self::new(self.dx / rhs.dx, self.dy / rhs.dy)
203    }
204}
205
206impl<T: en::Num> DivAssign for Vector<T> {
207    fn div_assign(&mut self, rhs: Self) {
208        *self = *self / rhs
209    }
210}
211
212impl<T: en::Num> Div<T> for Vector<T> {
213    type Output = Self;
214    fn div(self, rhs: T) -> Self::Output {
215        self.map(move |x| x / rhs)
216    }
217}
218
219impl<T: en::Num> DivAssign<T> for Vector<T> {
220    fn div_assign(&mut self, rhs: T) {
221        *self = *self / rhs
222    }
223}
224
225impl<T: en::Num> Rem for Vector<T> {
226    type Output = Self;
227
228    fn rem(self, rhs: Self) -> Self::Output {
229        Self::new(self.dx % rhs.dx, self.dy % rhs.dy)
230    }
231}
232
233impl<T: en::Num> RemAssign for Vector<T> {
234    fn rem_assign(&mut self, rhs: Self) {
235        *self = *self % rhs
236    }
237}
238
239impl<T: en::Num> Rem<T> for Vector<T> {
240    type Output = Self;
241    fn rem(self, rhs: T) -> Self::Output {
242        self.map(move |x| x % rhs)
243    }
244}
245
246impl<T: en::Num> RemAssign<T> for Vector<T> {
247    fn rem_assign(&mut self, rhs: T) {
248        *self = *self % rhs
249    }
250}
251
252impl<T: Neg<Output = T> + en::Num> Neg for Vector<T> {
253    type Output = Self;
254    fn neg(self) -> Self::Output {
255        self.map(move |x| -x)
256    }
257}
258
259impl<T: en::Float> From<Direction> for Vector<T> {
260    fn from(direction: Direction) -> Self {
261        direction.angle().unit_vector()
262    }
263}
264
265impl<T: en::Float> From<Cardinal> for Vector<T> {
266    fn from(cardinal: Cardinal) -> Self {
267        cardinal.angle().unit_vector()
268    }
269}
270
271#[cfg(feature = "euclid")]
272impl<T, U> From<Vector<T>> for euclid::Vector2D<T, U> {
273    fn from(v: Vector<T>) -> euclid::Vector2D<T, U> {
274        Self::new(v.dx, v.dy)
275    }
276}
277
278#[cfg(feature = "euclid")]
279impl<T, U> From<euclid::Vector2D<T, U>> for Vector<T> {
280    fn from(v: euclid::Vector2D<T, U>) -> Vector<T> {
281        Self { dx: v.x, dy: v.y }
282    }
283}