1use crate::*;
2
3#[derive(Clone, Copy, PartialEq, Eq, Debug)]
4#[repr(C)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6pub struct Vector<T> {
7 pub x: T,
8 pub y: T,
9}
10
11impl<T> Vector<T> {
12 #[inline]
13 pub fn new(x: T, y: T) -> Self {
14 Self { x, y }
15 }
16
17 #[inline]
18 pub fn map<R>(self, mut f: impl FnMut(T) -> R) -> Vector<R> {
19 Vector::new(f(self.x), f(self.y))
20 }
21}
22
23impl<T: ToPrimitive> Vector<T> {
24 #[inline]
25 pub fn cast<U: NumCast>(self) -> Option<Vector<U>> {
26 Some(Vector::new(U::from(self.x)?, U::from(self.y)?))
27 }
28}
29
30impl<T> Vector<T>
31where
32 T: std::ops::Add<T, Output = T> + std::ops::Mul<T, Output = T>,
33{
34 #[inline]
35 pub fn dot(self, rhs: impl Into<Self>) -> T {
36 let rhs = rhs.into();
37 self.x * rhs.x + self.y * rhs.y
38 }
39}
40
41impl<T> Vector<T>
42where
43 T: std::ops::Sub<T, Output = T> + std::ops::Mul<T, Output = T>,
44{
45 #[inline]
46 pub fn cross(self, rhs: impl Into<Self>) -> T {
47 let rhs = rhs.into();
48 self.x * rhs.y - self.y * rhs.x
49 }
50}
51
52impl<T> Vector<T>
53where
54 T: std::ops::Add<T, Output = T> + std::ops::Mul<T, Output = T> + Copy,
55{
56 #[inline]
57 pub fn abs_pow2(self) -> T {
58 self.x * self.x + self.y * self.y
59 }
60}
61
62impl<T: Float> Vector<T> {
63 #[inline]
64 pub fn abs(self) -> T {
65 T::sqrt(self.x.powi(2) + self.y.powi(2))
66 }
67}
68
69impl<T> PartialEq<(T, T)> for Vector<T>
70where
71 T: PartialEq,
72{
73 #[inline]
74 fn eq(&self, other: &(T, T)) -> bool {
75 self.x == other.0 && self.y == other.1
76 }
77}
78
79impl<T> PartialEq<[T; 2]> for Vector<T>
80where
81 T: PartialEq,
82{
83 #[inline]
84 fn eq(&self, other: &[T; 2]) -> bool {
85 self.x == other[0] && self.y == other[1]
86 }
87}
88
89impl<T> PartialEq<Vector<T>> for (T, T)
90where
91 T: PartialEq,
92{
93 #[inline]
94 fn eq(&self, other: &Vector<T>) -> bool {
95 self.0 == other.x && self.1 == other.y
96 }
97}
98
99impl<T> PartialEq<Vector<T>> for [T; 2]
100where
101 T: PartialEq,
102{
103 #[inline]
104 fn eq(&self, other: &Vector<T>) -> bool {
105 self[0] == other.x && self[1] == other.y
106 }
107}
108
109impl<T> From<(T, T)> for Vector<T> {
110 #[inline]
111 fn from(src: (T, T)) -> Vector<T> {
112 Vector::new(src.0, src.1)
113 }
114}
115
116impl<T: Copy> From<[T; 2]> for Vector<T> {
117 #[inline]
118 fn from(src: [T; 2]) -> Vector<T> {
119 Vector::new(src[0], src[1])
120 }
121}
122
123impl<T> From<Point<T>> for Vector<T> {
124 #[inline]
125 fn from(src: Point<T>) -> Vector<T> {
126 Vector::new(src.x, src.y)
127 }
128}
129
130impl<T> From<Size<T>> for Vector<T> {
131 #[inline]
132 fn from(src: Size<T>) -> Vector<T> {
133 Vector::new(src.width, src.height)
134 }
135}
136
137impl<T, U> std::ops::Add<U> for Vector<T>
138where
139 T: std::ops::Add<T, Output = T>,
140 U: Into<Self>,
141{
142 type Output = Self;
143
144 #[inline]
145 fn add(self, rhs: U) -> Self {
146 let rhs = rhs.into();
147 Self::new(self.x + rhs.x, self.y + rhs.y)
148 }
149}
150
151impl<T, U> std::ops::Sub<U> for Vector<T>
152where
153 T: std::ops::Sub<T, Output = T>,
154 U: Into<Self>,
155{
156 type Output = Self;
157
158 #[inline]
159 fn sub(self, rhs: U) -> Self {
160 let rhs = rhs.into();
161 Self::new(self.x - rhs.x, self.y - rhs.y)
162 }
163}
164
165impl<T> std::ops::Mul<T> for Vector<T>
166where
167 T: std::ops::Mul<T, Output = T> + Copy,
168{
169 type Output = Self;
170
171 #[inline]
172 fn mul(self, rhs: T) -> Self {
173 Self::new(self.x * rhs, self.y * rhs)
174 }
175}
176
177impl<T> std::ops::Div<T> for Vector<T>
178where
179 T: std::ops::Div<T, Output = T> + Copy,
180{
181 type Output = Self;
182
183 #[inline]
184 fn div(self, rhs: T) -> Self {
185 Self::new(self.x / rhs, self.y / rhs)
186 }
187}
188
189impl<T, U> std::ops::AddAssign<U> for Vector<T>
190where
191 T: std::ops::AddAssign<T>,
192 U: Into<Self>,
193{
194 #[inline]
195 fn add_assign(&mut self, rhs: U) {
196 let rhs = rhs.into();
197 self.x += rhs.x;
198 self.y += rhs.y;
199 }
200}
201
202impl<T, U> std::ops::SubAssign<U> for Vector<T>
203where
204 T: std::ops::SubAssign<T>,
205 U: Into<Self>,
206{
207 #[inline]
208 fn sub_assign(&mut self, rhs: U) {
209 let rhs = rhs.into();
210 self.x -= rhs.x;
211 self.y -= rhs.y;
212 }
213}
214
215impl<T> std::ops::MulAssign<T> for Vector<T>
216where
217 T: std::ops::MulAssign<T> + Copy,
218{
219 #[inline]
220 fn mul_assign(&mut self, rhs: T) {
221 self.x *= rhs;
222 self.y *= rhs;
223 }
224}
225
226impl<T> std::ops::DivAssign<T> for Vector<T>
227where
228 T: std::ops::DivAssign<T> + Copy,
229{
230 #[inline]
231 fn div_assign(&mut self, rhs: T) {
232 self.x /= rhs;
233 self.y /= rhs;
234 }
235}
236
237#[inline]
238pub fn vector<T>(x: T, y: T) -> Vector<T> {
239 Vector::new(x, y)
240}
241
242#[cfg(test)]
243mod tests {
244 use super::*;
245
246 #[test]
247 fn map_test() {
248 assert!(vector(1, 2).map(|x| x * 2) == (2, 4));
249 }
250
251 #[test]
252 #[allow(clippy::identity_op)]
253 fn dot_test() {
254 assert!(vector(1, 2).dot((3, 4)) == 1 * 3 + 2 * 4);
255 }
256
257 #[test]
258 #[allow(clippy::identity_op)]
259 fn cross_test() {
260 assert!(vector(3, 4).cross((1, 2)) == 3 * 2 - 1 * 4);
261 }
262
263 #[test]
264 fn abs_pow2_test() {
265 assert!(vector(2, 3).abs_pow2() == 2 * 2 + 3 * 3);
266 }
267
268 #[test]
269 fn abs_test() {
270 let d = vector(2.0, 3.0).abs() - f32::sqrt(2.0 * 2.0 + 3.0 * 3.0);
271 assert!(d.abs() <= f32::EPSILON);
272 }
273
274 #[test]
275 fn eq_test() {
276 assert!(vector(1, 2) == vector(1, 2));
277 assert!(vector(1, 2) == (1, 2));
278 assert!(vector(1, 2) == [1, 2]);
279 assert!((1, 2) == vector(1, 2));
280 assert!([1, 2] == vector(1, 2));
281 }
282
283 #[test]
284 fn add_test() {
285 let a = vector(1, 2);
286 let b = vector(6, 7);
287 let c = a + b;
288 assert!(c == (7, 9));
289 let c = a + (6, 7);
290 assert!(c == (7, 9));
291 }
292
293 #[test]
294 fn sub_test() {
295 let a = vector(1, 2);
296 let b = vector(6, 7);
297 let c = b - a;
298 assert!(c == (5, 5));
299 let c = b - (1, 2);
300 assert!(c == (5, 5));
301 }
302
303 #[test]
304 fn mul_test() {
305 let a = vector(1, 2);
306 let b = a * 2;
307 assert!(b == (2, 4));
308 }
309
310 #[test]
311 fn div_test() {
312 let a = vector(2, 6);
313 let b = a / 2;
314 assert!(b == (1, 3));
315 }
316
317 #[test]
318 fn add_assign_test() {
319 let mut a = vector(1, 2);
320 let b = vector(6, 7);
321 a += b;
322 assert!(a == (7, 9));
323 let mut a = vector(1, 2);
324 a += (6, 7);
325 assert!(a == (7, 9));
326 }
327
328 #[test]
329 fn sub_assign_test() {
330 let mut a = vector(6, 7);
331 let b = vector(1, 2);
332 a -= b;
333 assert!(a == (5, 5));
334 let mut a = vector(6, 7);
335 a -= (1, 2);
336 assert!(a == (5, 5));
337 }
338
339 #[test]
340 fn mul_assign_test() {
341 let mut a = vector(1, 2);
342 a *= 2;
343 assert!(a == (2, 4));
344 }
345
346 #[test]
347 fn div_assign_test() {
348 let mut a = vector(3, 6);
349 a /= 3;
350 assert!(a == (1, 2));
351 }
352}