1use std::convert::TryInto;
18
19use num_traits::{AsPrimitive, Zero};
20use rusttype::Point;
21
22use crate::numeric::{PrimitiveZero, RoundFloat};
23
24pub type Vec2 = Vector2<f32>;
26
27pub type IVec2 = Vector2<i32>;
29
30pub type UVec2 = Vector2<u32>;
32
33#[repr(C)]
36#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
37pub struct Vector2<T>
38{
39 pub x: T,
41 pub y: T
43}
44
45impl<T> Vector2<T>
46{
47 #[inline]
50 #[must_use]
51 pub const fn new(x: T, y: T) -> Self
52 {
53 Vector2 { x, y }
54 }
55}
56
57impl<T: PrimitiveZero> Vector2<T>
58{
59 pub const ZERO: Vector2<T> = Vector2::new(T::ZERO, T::ZERO);
62
63 #[inline]
66 #[must_use]
67 pub fn new_x(x: T) -> Self
68 {
69 Vector2 { x, y: T::ZERO }
70 }
71
72 #[inline]
75 #[must_use]
76 pub fn new_y(y: T) -> Self
77 {
78 Vector2 { x: T::ZERO, y }
79 }
80}
81
82impl<T> Vector2<T>
83where
84 T: Copy + std::ops::Mul<Output = T> + std::ops::Add<Output = T>
85{
86 #[inline]
88 #[must_use]
89 pub fn magnitude_squared(&self) -> T
90 {
91 self.x * self.x + self.y * self.y
92 }
93}
94
95impl<T> Vector2<T>
96where
97 T: AsPrimitive<f32>
98 + Copy
99 + std::ops::Mul<Output = T>
100 + std::ops::Add<Output = T>
101 + std::ops::Div<f32, Output = T>
102{
103 #[inline]
105 #[must_use]
106 pub fn magnitude(&self) -> f32
107 {
108 (self.magnitude_squared().as_()).sqrt()
109 }
110
111 #[inline]
115 #[must_use]
116 pub fn normalize(&self) -> Option<Vector2<T>>
117 {
118 let magnitude = self.magnitude();
119
120 if magnitude.is_zero() {
121 return None;
122 }
123
124 Some(Vector2::new(self.x / magnitude, self.y / magnitude))
125 }
126}
127
128impl<T: std::ops::Neg<Output = T> + Copy> Vector2<T>
129{
130 #[inline]
132 #[must_use]
133 pub fn rotate_90_degrees_clockwise(&self) -> Vector2<T>
134 {
135 Vector2::new(-self.y, self.x)
136 }
137
138 #[inline]
140 #[must_use]
141 pub fn rotate_90_degrees_anticlockwise(&self) -> Vector2<T>
142 {
143 Vector2::new(self.y, -self.x)
144 }
145}
146
147impl<T: num_traits::AsPrimitive<f32>> Vector2<T>
148{
149 #[inline]
152 #[must_use]
153 pub fn into_f32(self) -> Vec2
154 {
155 Vector2::new(self.x.as_(), self.y.as_())
156 }
157}
158
159impl<T: num_traits::AsPrimitive<i32>> Vector2<T>
160{
161 #[inline]
164 #[must_use]
165 pub fn into_i32(self) -> IVec2
166 {
167 Vector2::new(self.x.as_(), self.y.as_())
168 }
169}
170
171impl<T: num_traits::AsPrimitive<u32>> Vector2<T>
172{
173 #[inline]
176 #[must_use]
177 pub fn into_u32(self) -> UVec2
178 {
179 Vector2::new(self.x.as_(), self.y.as_())
180 }
181}
182
183impl<T: TryInto<i32>> Vector2<T>
184{
185 #[inline]
188 pub fn try_into_i32(self) -> Result<IVec2, T::Error>
189 {
190 Ok(Vector2::new(self.x.try_into()?, self.y.try_into()?))
191 }
192}
193
194impl<T> From<(T, T)> for Vector2<T>
195where
196 T: Copy
197{
198 #[inline]
199 fn from(value: (T, T)) -> Self
200 {
201 Vector2::new(value.0, value.1)
202 }
203}
204
205impl<T> From<&(T, T)> for Vector2<T>
206where
207 T: Copy
208{
209 #[inline]
210 fn from(value: &(T, T)) -> Self
211 {
212 Vector2::new(value.0, value.1)
213 }
214}
215
216impl<T> From<&Self> for Vector2<T>
217where
218 T: Copy
219{
220 #[inline]
221 fn from(value: &Self) -> Self
222 {
223 *value
224 }
225}
226
227impl<T> From<&mut Self> for Vector2<T>
228where
229 T: Copy
230{
231 #[inline]
232 fn from(value: &mut Self) -> Self
233 {
234 *value
235 }
236}
237
238impl<T: Copy + std::ops::Add<Output = T>, R: Into<Self>> std::ops::Add<R> for Vector2<T>
239{
240 type Output = Vector2<T>;
241
242 #[inline]
243 fn add(self, rhs: R) -> Self::Output
244 {
245 let rhs = rhs.into();
246 Vector2::new(self.x + rhs.x, self.y + rhs.y)
247 }
248}
249
250impl<T: Copy + std::ops::Add<Output = T>, R: Into<Vector2<T>>> std::ops::Add<R>
251 for &Vector2<T>
252{
253 type Output = Vector2<T>;
254
255 #[inline]
256 fn add(self, rhs: R) -> Self::Output
257 {
258 let rhs = rhs.into();
259 Vector2::new(self.x + rhs.x, self.y + rhs.y)
260 }
261}
262
263impl<T: Copy + std::ops::Sub<Output = T>, R: Into<Self>> std::ops::Sub<R> for Vector2<T>
264{
265 type Output = Vector2<T>;
266
267 #[inline]
268 fn sub(self, rhs: R) -> Self::Output
269 {
270 let rhs = rhs.into();
271 Vector2::new(self.x - rhs.x, self.y - rhs.y)
272 }
273}
274
275impl<T: Copy + std::ops::Sub<Output = T>, R: Into<Vector2<T>>> std::ops::Sub<R>
276 for &Vector2<T>
277{
278 type Output = Vector2<T>;
279
280 #[inline]
281 fn sub(self, rhs: R) -> Self::Output
282 {
283 let rhs = rhs.into();
284 Vector2::new(self.x - rhs.x, self.y - rhs.y)
285 }
286}
287
288impl<T: Copy + std::ops::AddAssign, R: Into<Vector2<T>>> std::ops::AddAssign<R>
289 for Vector2<T>
290{
291 #[inline]
292 fn add_assign(&mut self, rhs: R)
293 {
294 let rhs = rhs.into();
295 self.x += rhs.x;
296 self.y += rhs.y;
297 }
298}
299
300impl<T: Copy + std::ops::AddAssign, R: Into<Vector2<T>>> std::ops::AddAssign<R>
301 for &mut Vector2<T>
302{
303 #[inline]
304 fn add_assign(&mut self, rhs: R)
305 {
306 let rhs = rhs.into();
307 self.x += rhs.x;
308 self.y += rhs.y;
309 }
310}
311
312impl<T: Copy + std::ops::SubAssign, R: Into<Vector2<T>>> std::ops::SubAssign<R>
313 for Vector2<T>
314{
315 #[inline]
316 fn sub_assign(&mut self, rhs: R)
317 {
318 let rhs = rhs.into();
319 self.x -= rhs.x;
320 self.y -= rhs.y;
321 }
322}
323
324impl<T: Copy + std::ops::SubAssign, R: Into<Vector2<T>>> std::ops::SubAssign<R>
325 for &mut Vector2<T>
326{
327 #[inline]
328 fn sub_assign(&mut self, rhs: R)
329 {
330 let rhs = rhs.into();
331 self.x -= rhs.x;
332 self.y -= rhs.y;
333 }
334}
335
336impl<T: Copy + std::ops::MulAssign> std::ops::MulAssign<T> for Vector2<T>
337{
338 #[inline]
339 fn mul_assign(&mut self, factor: T)
340 {
341 self.x *= factor;
342 self.y *= factor;
343 }
344}
345
346impl<T: Copy + std::ops::MulAssign> std::ops::MulAssign<T> for &mut Vector2<T>
347{
348 #[inline]
349 fn mul_assign(&mut self, factor: T)
350 {
351 self.x *= factor;
352 self.y *= factor;
353 }
354}
355
356impl<T: Copy + std::ops::DivAssign> std::ops::DivAssign<T> for Vector2<T>
357{
358 #[inline]
359 fn div_assign(&mut self, divisor: T)
360 {
361 self.x /= divisor;
362 self.y /= divisor;
363 }
364}
365
366impl<T: Copy + std::ops::DivAssign> std::ops::DivAssign<T> for &mut Vector2<T>
367{
368 #[inline]
369 fn div_assign(&mut self, divisor: T)
370 {
371 self.x /= divisor;
372 self.y /= divisor;
373 }
374}
375
376impl<T: Copy + std::ops::Mul<Output = T>> std::ops::Mul<T> for &Vector2<T>
377{
378 type Output = Vector2<T>;
379
380 #[inline]
381 fn mul(self, rhs: T) -> Self::Output
382 {
383 Vector2::new(self.x * rhs, self.y * rhs)
384 }
385}
386
387impl<T: Copy + std::ops::Mul<Output = T>> std::ops::Mul<T> for Vector2<T>
388{
389 type Output = Vector2<T>;
390
391 #[inline]
392 fn mul(self, rhs: T) -> Self::Output
393 {
394 Vector2::new(self.x * rhs, self.y * rhs)
395 }
396}
397
398impl<T: Copy + std::ops::Div<Output = T>> std::ops::Div<T> for &Vector2<T>
399{
400 type Output = Vector2<T>;
401
402 #[inline]
403 fn div(self, rhs: T) -> Self::Output
404 {
405 Vector2::new(self.x / rhs, self.y / rhs)
406 }
407}
408
409impl<T: Copy + std::ops::Div<Output = T>> std::ops::Div<T> for Vector2<T>
410{
411 type Output = Vector2<T>;
412
413 #[inline]
414 fn div(self, rhs: T) -> Self::Output
415 {
416 Vector2::new(self.x / rhs, self.y / rhs)
417 }
418}
419
420impl<T: RoundFloat> RoundFloat for Vector2<T>
421{
422 fn round(&self) -> Self
423 {
424 Vector2::new(self.x.round(), self.y.round())
425 }
426}
427
428impl<T> From<Point<T>> for Vector2<T>
429{
430 #[inline]
431 fn from(point: Point<T>) -> Self
432 {
433 Vector2::new(point.x, point.y)
434 }
435}
436
437#[cfg(test)]
438mod test
439{
440 use super::*;
441
442 #[test]
443 fn test_arithmetic()
444 {
445 assert_eq!(
446 Vector2::new(15, 20),
447 Vector2::new(10, 4) + Vector2::new(5, 16)
448 );
449
450 assert_eq!(
451 Vector2::new(5, -12),
452 Vector2::new(10, 4) - Vector2::new(5, 16)
453 );
454
455 assert_eq!(IVec2::new(-5, 10), IVec2::new(3, 10) - IVec2::new_x(8));
456
457 assert_eq!(IVec2::new(-5, 17), IVec2::new(-5, 10) + IVec2::new_y(7));
458 }
459
460 #[test]
461 fn test_arithmetic_ref()
462 {
463 assert_eq!(
464 Vector2::new(15, 20),
465 Vector2::new(10, 4) + &Vector2::new(5, 16)
466 );
467
468 assert_eq!(
469 Vector2::new(5, -12),
470 Vector2::new(10, 4) - &Vector2::new(5, 16)
471 );
472
473 assert_eq!(
474 Vector2::new(15, 20),
475 &Vector2::new(10, 4) + Vector2::new(5, 16)
476 );
477
478 assert_eq!(
479 Vector2::new(5, -12),
480 &Vector2::new(10, 4) - Vector2::new(5, 16)
481 );
482
483 assert_eq!(
484 Vector2::new(15, 20),
485 &Vector2::new(10, 4) + &Vector2::new(5, 16)
486 );
487
488 assert_eq!(
489 Vector2::new(5, -12),
490 &Vector2::new(10, 4) - &Vector2::new(5, 16)
491 );
492 }
493
494 #[test]
495 fn test_arithmetic_tuples()
496 {
497 assert_eq!(Vector2::new(15, 20), Vector2::new(10, 4) + (5, 16));
498
499 assert_eq!(Vector2::new(15, 20), Vector2::new(10, 4) + &(5, 16));
500
501 assert_eq!(Vector2::new(15, 20), &Vector2::new(10, 4) + (5, 16));
502
503 assert_eq!(Vector2::new(15, 20), &Vector2::new(10, 4) + &(5, 16));
504
505 assert_eq!(Vector2::new(5, -12), Vector2::new(10, 4) - (5, 16));
506
507 assert_eq!(Vector2::new(5, -12), Vector2::new(10, 4) - &(5, 16));
508
509 assert_eq!(Vector2::new(5, -12), &Vector2::new(10, 4) - (5, 16));
510
511 assert_eq!(Vector2::new(5, -12), &Vector2::new(10, 4) - &(5, 16));
512 }
513 #[test]
514 fn test_add_assign()
515 {
516 let mut left = Vector2::new(1, 2);
517 let right = Vector2::new(3, 4);
518 left += right;
519 assert_eq!(left, Vector2::new(4, 6));
520 left += &right;
521 assert_eq!(left, Vector2::new(7, 10));
522 {
523 let mut ref_left = &mut left;
524 ref_left += right;
525 }
526 assert_eq!(left, Vector2::new(10, 14));
527 {
528 let mut ref_left = &mut left;
529 ref_left += right;
530 }
531 assert_eq!(left, Vector2::new(13, 18));
532 }
533
534 #[test]
535 fn test_sub_assign()
536 {
537 let mut left = Vector2::new(9, 8);
538 let right = Vector2::new(1, 2);
539 left -= right;
540 assert_eq!(left, Vector2::new(8, 6));
541 left -= &right;
542 assert_eq!(left, Vector2::new(7, 4));
543 {
544 let mut ref_left = &mut left;
545 ref_left -= right;
546 }
547 assert_eq!(left, Vector2::new(6, 2));
548 {
549 let mut ref_left = &mut left;
550 ref_left -= right;
551 }
552 assert_eq!(left, Vector2::new(5, 0));
553 }
554
555 #[test]
556 fn test_mul_assign()
557 {
558 let mut left = Vector2::new(2, 3);
559 left *= 5;
560 assert_eq!(left, Vector2::new(10, 15));
561 {
562 let mut ref_left = &mut left;
563 ref_left *= 2;
564 }
565 assert_eq!(left, Vector2::new(20, 30));
566 }
567
568 #[test]
569 fn test_div_assign()
570 {
571 let mut left = Vector2::new(12, 8);
572 left /= 2;
573 assert_eq!(left, Vector2::new(6, 4));
574 {
575 let mut ref_left = &mut left;
576 ref_left /= 2;
577 }
578 assert_eq!(left, Vector2::new(3, 2));
579 }
580}