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}