nuit_core/utils/
vec2.rs

1use nuit_derive::ApproxEq;
2use serde::{Serialize, Deserialize};
3use std::{fmt, ops::{Add, Sub, Mul, Div, DivAssign, MulAssign, AddAssign, SubAssign, Neg}};
4
5use super::Zero;
6
7/// A 2D vector (or position).
8#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, ApproxEq, Hash, Serialize, Deserialize)]
9pub struct Vec2<T> {
10    pub x: T,
11    pub y: T,
12}
13
14impl<T> Zero for Vec2<T> where T: Zero {
15    /// The coordinate origin or zero direction vector, i.e. (0, 0).
16    const ZERO: Self = Self::new(T::ZERO, T::ZERO);
17}
18
19impl<T> Vec2<T> {
20    /// Creates a new vector from the given components.
21    #[inline]
22    pub const fn new(x: T, y: T) -> Self {
23        Self { x, y }
24    }
25}
26
27impl<T> Vec2<T> where T: Default {
28    /// Creates a new vector with the given x component and the default y.
29    #[inline]
30    pub fn with_x(x: T) -> Self {
31        Self { x, y: T::default() }
32    }
33
34    /// Creates a new vector with the given y component and the default x.
35    #[inline]
36    pub fn with_y(y: T) -> Self {
37        Self { x: T::default(), y }
38    }
39}
40
41impl<T> Vec2<T> where T: Add<Output = T> + Mul<Output = T> + Copy {
42    /// The squared length of this vector.
43    #[inline]
44    pub fn squared_length(self) -> T { self.x * self.x + self.y * self.y }
45}
46
47impl<T> Add for Vec2<T> where T: Add<Output = T> {
48    type Output = Self;
49
50    fn add(self, rhs: Self) -> Self {
51        Self::new(self.x + rhs.x, self.y + rhs.y)
52    }
53}
54
55impl<T> AddAssign<Vec2<T>> for Vec2<T> where T: AddAssign {
56    fn add_assign(&mut self, rhs: Self) {
57        self.x += rhs.x;
58        self.y += rhs.y;
59    }
60}
61
62impl<T> Sub for Vec2<T> where T: Sub<Output = T> {
63    type Output = Self;
64
65    fn sub(self, rhs: Self) -> Self {
66        Self::new(self.x - rhs.x, self.y - rhs.y)
67    }
68}
69
70impl<T> SubAssign<Vec2<T>> for Vec2<T> where T: SubAssign {
71    fn sub_assign(&mut self, rhs: Self) {
72        self.x -= rhs.x;
73        self.y -= rhs.y;
74    }
75}
76
77impl<T> Mul<T> for Vec2<T> where T: Mul<Output = T> + Copy {
78    type Output = Self;
79
80    fn mul(self, rhs: T) -> Self {
81        Self::new(self.x * rhs, self.y * rhs)
82    }
83}
84
85impl<T> MulAssign<T> for Vec2<T> where T: MulAssign + Copy {
86    fn mul_assign(&mut self, rhs: T) {
87        self.x *= rhs;
88        self.y *= rhs;
89    }
90}
91
92impl<T> Div<T> for Vec2<T> where T: Div<Output = T> + Copy {
93    type Output = Self;
94
95    fn div(self, rhs: T) -> Self {
96        Self::new(self.x / rhs, self.y / rhs)
97    }
98}
99
100impl<T> DivAssign<T> for Vec2<T> where T: DivAssign + Copy {
101    fn div_assign(&mut self, rhs: T) {
102        self.x /= rhs;
103        self.y /= rhs;
104    }
105}
106
107impl<T> Neg for Vec2<T> where T: Neg<Output = T> {
108    type Output = Self;
109
110    fn neg(self) -> Self {
111        Self::new(-self.x, -self.y)
112    }
113}
114
115impl<T> fmt::Display for Vec2<T> where T: fmt::Display {
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        write!(f, "({}, {})", self.x, self.y)
118    }
119}