math2d/
vector2i.rs

1//! Mathematical vector on the 2D (x, y) plane.
2
3use sizeu::Sizeu;
4use vector2f::Vector2f;
5
6use std::ops::{Add, Div, Mul, Neg, Sub};
7
8/// Mathematical vector on the 2D (x, y) plane.
9#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
10#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))]
11#[repr(C)]
12pub struct Vector2i {
13    /// Horizontal component.
14    pub x: i32,
15    /// Vertical component.
16    pub y: i32,
17}
18
19impl Vector2i {
20    /// The zero vector. Addition with the zero vector is the identity function.
21    pub const ZERO: Vector2i = Vector2i { x: 0, y: 0 };
22
23    /// Construct a vector from the components
24    #[inline]
25    pub fn new(x: i32, y: i32) -> Self {
26        Vector2i { x, y }
27    }
28
29    /// Converts this vector to floating point components.
30    #[inline]
31    pub fn to_f32(self) -> Vector2f {
32        Vector2f {
33            x: self.x as f32,
34            y: self.y as f32,
35        }
36    }
37
38    /// Converts this vector to a size. Ensure the values are positive or you
39    /// will experience casting underflow.
40    #[inline]
41    pub fn as_size(self) -> Sizeu {
42        Sizeu {
43            width: self.x as u32,
44            height: self.y as u32,
45        }
46    }
47
48    /// Returns the absolute values of the components.
49    #[inline]
50    pub fn abs(self) -> Vector2i {
51        Vector2i::new(self.x.abs(), self.y.abs())
52    }
53}
54
55impl<V> Add<V> for Vector2i
56where
57    V: Into<Vector2i>,
58{
59    type Output = Vector2i;
60
61    #[inline]
62    fn add(self, rhs: V) -> Vector2i {
63        let rhs = rhs.into();
64        Vector2i {
65            x: self.x + rhs.x,
66            y: self.y + rhs.y,
67        }
68    }
69}
70
71impl<V> Sub<V> for Vector2i
72where
73    V: Into<Vector2i>,
74{
75    type Output = Vector2i;
76
77    #[inline]
78    fn sub(self, rhs: V) -> Vector2i {
79        let rhs = rhs.into();
80        Vector2i {
81            x: self.x - rhs.x,
82            y: self.y - rhs.y,
83        }
84    }
85}
86
87impl Neg for Vector2i {
88    type Output = Vector2i;
89
90    #[inline]
91    fn neg(self) -> Vector2i {
92        Vector2i {
93            x: -self.x,
94            y: -self.y,
95        }
96    }
97}
98
99impl Mul<i32> for Vector2i {
100    type Output = Vector2i;
101
102    #[inline]
103    fn mul(self, rhs: i32) -> Vector2i {
104        Vector2i {
105            x: self.x * rhs,
106            y: self.y * rhs,
107        }
108    }
109}
110
111impl Mul<Vector2i> for i32 {
112    type Output = Vector2i;
113
114    #[inline]
115    fn mul(self, rhs: Vector2i) -> Vector2i {
116        Vector2i {
117            x: self * rhs.x,
118            y: self * rhs.y,
119        }
120    }
121}
122
123impl Div<i32> for Vector2i {
124    type Output = Vector2i;
125
126    #[inline]
127    fn div(self, rhs: i32) -> Vector2i {
128        Vector2i {
129            x: self.x / rhs,
130            y: self.y / rhs,
131        }
132    }
133}
134
135impl Div<Vector2i> for i32 {
136    type Output = Vector2i;
137
138    #[inline]
139    fn div(self, rhs: Vector2i) -> Vector2i {
140        Vector2i {
141            x: self / rhs.x,
142            y: self / rhs.y,
143        }
144    }
145}
146
147impl From<[i32; 2]> for Vector2i {
148    #[inline]
149    fn from(v: [i32; 2]) -> Vector2i {
150        Vector2i::new(v[0], v[1])
151    }
152}
153
154impl From<Vector2i> for [i32; 2] {
155    fn from(v: Vector2i) -> [i32; 2] {
156        [v.x, v.y]
157    }
158}
159
160#[cfg(feature = "mint")]
161impl From<Vector2i> for mint::Vector2<i32> {
162    #[inline]
163    fn from(p: Vector2i) -> mint::Vector2<i32> {
164        mint::Vector2 { x: p.x, y: p.y }
165    }
166}
167
168#[cfg(feature = "mint")]
169impl From<mint::Vector2<i32>> for Vector2i {
170    #[inline]
171    fn from(p: mint::Vector2<i32>) -> Vector2i {
172        Vector2i { x: p.x, y: p.y }
173    }
174}
175
176#[cfg(test)]
177mod tests {
178    use vector2i::Vector2i;
179
180    #[test]
181    fn addition() {
182        let val = Vector2i::ZERO + [1, 2] + [3, 4];
183        assert_eq!(val, Vector2i::new(4, 6));
184    }
185
186    #[test]
187    fn subtraction() {
188        let val = Vector2i::ZERO - [5, 3] + [2, 0] - [1, 1];
189        assert_eq!(val, Vector2i::new(-4, -4));
190    }
191}