gecl/
vector.rs

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}