physdes/
vector2.rs

1use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
2use num_traits::{Num, Signed, Zero};
3
4/// The code defines a generic struct called Vector2 with two fields, x_ and y_.
5///
6/// Properties:
7///
8/// * `x_`: The `x_` property represents the x-coordinate of the Vector2 object. It is of type `T`,
9///         which means it can be any type specified when creating an instance of the Vector2 struct.
10/// * `y_`: The `y_` property is the y-coordinate of the `Vector2` object. It represents the vertical
11///         position of the vector in a 2D coordinate system.
12#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug, Default)]
13// #[repr(C)]
14pub struct Vector2<T1, T2> {
15    /// x portion of the Vector2 object
16    pub x_: T1,
17    /// y portion of the Vector2 object
18    pub y_: T2,
19}
20
21impl<T1, T2> Vector2<T1, T2> {
22    /// The function `new` creates a new Vector2 with the given x and y values.
23    ///
24    /// Arguments:
25    ///
26    /// * `x_`: The parameter `x_` represents the x-coordinate of the Vector2.
27    /// * `y_`: The parameter `y_` represents the y-coordinate of the Vector2. It is of type `T`, which
28    ///         means it can be any type that is specified when the Vector2 is created.
29    ///
30    /// Returns:
31    ///
32    /// The `new` function is returning a new instance of the `Vector2` struct with the provided `x_`
33    /// and `y_` values.
34    ///
35    /// # Example
36    ///
37    /// ```
38    /// use physdes::vector2::Vector2;
39    ///
40    /// assert_eq!(Vector2::new(1, 2), Vector2 { x_: 1, y_: 2 });
41    /// assert_eq!(Vector2::new(3, 4), Vector2 { x_: 3, y_: 4 });
42    /// ```
43    #[inline]
44    pub const fn new(x_: T1, y_: T2) -> Self {
45        Vector2 { x_, y_ }
46    }
47}
48
49impl<T1: Clone + Num> Vector2<T1, T1> {
50    /// The `dot` function calculates the dot product of two vectors.
51    ///
52    /// Arguments:
53    ///
54    /// * `other`: The `other` parameter is of the same type as `self`, which means it is an instance of
55    ///             the same struct or class that the `dot` method is defined in.
56    ///
57    /// Returns:
58    ///
59    /// The dot product of two vectors is being returned.
60    ///
61    /// # Example
62    ///
63    /// ```
64    /// use physdes::vector2::Vector2;
65    ///
66    /// assert_eq!(Vector2::new(1, 2).dot(&Vector2::new(3, 4)), 11);
67    /// assert_eq!(Vector2::new(3, 4).dot(&Vector2::new(1, 2)), 11);
68    /// ```
69    #[inline]
70    pub fn dot(&self, other: &Self) -> T1 {
71        self.x_.clone() * other.x_.clone() + self.y_.clone() * other.y_.clone()
72    }
73
74    /// The `cross` function calculates the cross product of two vectors.
75    ///
76    /// Arguments:
77    ///
78    /// * `other`: The `other` parameter is of type `Self`, which means it is the same type as the
79    ///             current object.
80    ///
81    /// # Example
82    ///
83    /// ```
84    /// use physdes::vector2::Vector2;
85    ///
86    /// assert_eq!(Vector2::new(1, 2).cross(&Vector2::new(3, 4)), -2);
87    /// assert_eq!(Vector2::new(3, 4).cross(&Vector2::new(1, 2)), 2);
88    /// ```
89    #[inline]
90    pub fn cross(&self, other: &Self) -> T1 {
91        self.x_.clone() * other.y_.clone() - self.y_.clone() * other.x_.clone()
92    }
93
94    // #[inline]
95    // pub fn norm_sqr(&self) -> T {
96    //     self.dot(self)
97    // }
98
99    /// The `scale` function multiplies the vector by a scalar value.
100    ///
101    /// Arguments:
102    ///
103    /// * `t`: The parameter `t` is a scalar value that will be used to multiply each component of
104    ///         `self`.
105    ///
106    /// Returns:
107    ///
108    /// The `scale` method returns a new instance of the same type as `self`.
109    /// Multiplies `self` by the scalar `t`.
110    ///
111    /// # Example
112    ///
113    /// ```
114    /// use physdes::vector2::Vector2;
115    ///
116    /// assert_eq!(Vector2::new(1, 2).scale(3), Vector2::new(3, 6));
117    /// assert_eq!(Vector2::new(3, 4).scale(2), Vector2::new(6, 8));
118    /// ```
119    #[inline]
120    pub fn scale(&self, t: T1) -> Self {
121        Self::new(self.x_.clone() * t.clone(), self.y_.clone() * t)
122    }
123
124    /// The `unscale` function divides the coordinates of a vector by a scalar value.
125    ///
126    /// Arguments:
127    ///
128    /// * `t`: The parameter `t` is a scalar value that is used to divide the `self` object. It is of
129    ///         type `T`, which is a generic type parameter. The division operation is performed on the `x_` and
130    ///         `y_` fields of the `self` object.
131    ///
132    /// Returns:
133    ///
134    /// The `unscale` method returns a new instance of the same type as `self`.
135    /// Divides `self` by the scalar `t`.
136    ///
137    /// # Example
138    ///
139    /// ```
140    /// use physdes::vector2::Vector2;
141    ///
142    /// assert_eq!(Vector2::new(3, 6).unscale(3), Vector2::new(1, 2));
143    /// assert_eq!(Vector2::new(6, 8).unscale(2), Vector2::new(3, 4));
144    /// ```
145    #[inline]
146    pub fn unscale(&self, t: T1) -> Self {
147        Self::new(self.x_.clone() / t.clone(), self.y_.clone() / t)
148    }
149}
150
151impl<T1: Clone + Signed> Vector2<T1, T1> {
152    /// The `l1_norm` function calculates the Manhattan distance from the origin.
153    ///
154    /// [Manhattan distance]: https://en.wikipedia.org/wiki/Taxicab_geometry
155    ///
156    /// Returns:
157    ///
158    /// The L1 norm, which is the Manhattan distance from the origin.
159    /// Returns the L1 norm `|x_| + |y_|` -- the [Manhattan distance] from the origin.
160    ///
161    /// # Example
162    ///
163    /// ```
164    /// use physdes::vector2::Vector2;
165    ///
166    /// assert_eq!(Vector2::new(1, 2).l1_norm(), 3);
167    /// assert_eq!(Vector2::new(3, 4).l1_norm(), 7);
168    /// ```
169    #[inline]
170    pub fn l1_norm(&self) -> T1 {
171        self.x_.abs() + self.y_.abs()
172    }
173}
174
175impl<T1: Clone + PartialOrd> Vector2<T1, T1> {
176    /// The `norm_inf` function returns the maximum absolute value between `x_` and `y_`.
177    ///
178    /// Returns:
179    ///
180    /// The `norm_inf` function returns the maximum value between `|x_|` and `|y_|`.
181    /// Returns the infinity norm `max(|x_| + |y_|)`
182    ///
183    /// # Example
184    ///
185    /// ```
186    /// use physdes::vector2::Vector2;
187    ///
188    /// assert_eq!(Vector2::new(1, 2).norm_inf(), 2);
189    /// assert_eq!(Vector2::new(3, 4).norm_inf(), 4);
190    /// ```
191    #[inline]
192    pub fn norm_inf(&self) -> T1 {
193        if self.x_ > self.y_ {
194            self.x_.clone()
195        } else {
196            self.y_.clone()
197        }
198    }
199}
200
201// (a, b) + (c, d) == (a + c), (b + d)
202impl<T1: Clone + Num, T2: Clone + Num> Add<Vector2<T1, T2>> for Vector2<T1, T2> {
203    type Output = Self;
204
205    /// The function `add` takes two values of the same type and returns their sum.
206    ///
207    /// Arguments:
208    ///
209    /// * `other`: The `other` parameter is of the same type as `self` and represents the other object
210    ///             that you want to add to `self`.
211    ///
212    /// # Example
213    ///
214    /// ```
215    /// use physdes::vector2::Vector2;
216    /// use std::ops::Add;
217    ///
218    /// assert_eq!(Vector2::new(1, 2).add(Vector2::new(3, 4)), Vector2::new(4, 6));
219    /// assert_eq!(Vector2::new(3, 4).add(Vector2::new(1, 2)), Vector2::new(4, 6));
220    /// ```
221    #[inline]
222    fn add(self, other: Self) -> Self::Output {
223        Self::Output::new(self.x_ + other.x_, self.y_ + other.y_)
224    }
225}
226
227// (a, b) - (c, d) == (a - c), (b - d)
228impl<T1: Clone + Num, T2: Clone + Num> Sub<Vector2<T1, T2>> for Vector2<T1, T2> {
229    type Output = Self;
230
231    /// The function subtracts the coordinates of two points and returns a new point.
232    ///
233    /// Arguments:
234    ///
235    /// * `other`: The `other` parameter is of the same type as `self` and represents the other value
236    ///             that you want to subtract from `self`.
237    ///
238    /// # Example
239    ///
240    /// ```
241    /// use physdes::vector2::Vector2;
242    /// use std::ops::Sub;
243    ///
244    /// assert_eq!(Vector2::new(1, 2).sub(Vector2::new(3, 4)), Vector2::new(-2, -2));
245    /// assert_eq!(Vector2::new(3, 4).sub(Vector2::new(1, 2)), Vector2::new(2, 2));
246    /// ```
247    #[inline]
248    fn sub(self, other: Self) -> Self::Output {
249        Self::Output::new(self.x_ - other.x_, self.y_ - other.y_)
250    }
251}
252
253// Op Assign
254
255mod opassign {
256    use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
257
258    use num_traits::NumAssign;
259
260    use crate::Vector2;
261
262    impl<T1: Clone + NumAssign, T2: Clone + NumAssign> AddAssign for Vector2<T1, T2> {
263        /// The function `add_assign` adds the values of `other.x_` and `other.y_` to `self.x_` and
264        /// `self.y_` respectively.
265        ///
266        /// Arguments:
267        ///
268        /// * `other`: The "other" parameter is of type Self, which means it is a reference to another
269        ///             instance of the same struct or class that the method is defined in. In this case, it
270        ///             represents another instance of the struct or class that has the same fields or properties as
271        ///             self.
272        ///
273        /// # Example
274        ///
275        /// ```
276        /// use physdes::vector2::Vector2;
277        /// use std::ops::AddAssign;
278        ///
279        /// let mut v = Vector2::new(1, 2);
280        /// let v2 = Vector2::new(3, 4);
281        /// v.add_assign(v2);
282        /// assert_eq!(v, Vector2::new(4, 6));
283        /// ```
284        fn add_assign(&mut self, other: Self) {
285            self.x_ += other.x_;
286            self.y_ += other.y_;
287        }
288    }
289
290    impl<T1: Clone + NumAssign, T2: Clone + NumAssign> SubAssign for Vector2<T1, T2> {
291        /// The function subtracts the values of another object from the values of the current object.
292        ///
293        /// Arguments:
294        ///
295        /// * `other`: The parameter "other" is of type Self, which means it is a reference to another
296        ///             instance of the same struct or class that the method is defined in. In this case, it is a
297        ///             reference to another instance of the struct or class that has the same fields as self
298        ///             (x_ and y_)
299        ///
300        /// # Example
301        ///
302        /// ```
303        /// use physdes::vector2::Vector2;
304        /// use std::ops::SubAssign;
305        /// let mut v = Vector2::new(1, 2);
306        /// let v2 = Vector2::new(3, 4);
307        /// v.sub_assign(v2);
308        /// assert_eq!(v, Vector2::new(-2, -2));
309        /// ```
310        fn sub_assign(&mut self, other: Self) {
311            self.x_ -= other.x_;
312            self.y_ -= other.y_;
313        }
314    }
315
316    impl<T1: Clone + NumAssign> MulAssign<T1> for Vector2<T1, T1> {
317        /// The function multiplies the values of self.x_ and self.y_ by the value of other.
318        ///
319        /// Arguments:
320        ///
321        /// * `other`: The parameter `other` is of type `T`, which means it can be any type that
322        ///             implements the `Clone` trait.
323        ///
324        /// # Example
325        ///
326        /// ```
327        /// use physdes::vector2::Vector2;
328        /// use std::ops::MulAssign;
329        ///
330        /// let mut v = Vector2::new(1, 2);
331        /// v.mul_assign(3);
332        /// assert_eq!(v, Vector2::new(3, 6));
333        /// ```
334        fn mul_assign(&mut self, other: T1) {
335            self.x_ *= other.clone();
336            self.y_ *= other;
337        }
338    }
339
340    impl<T1: Clone + NumAssign> DivAssign<T1> for Vector2<T1, T1> {
341        /// The function divides the values of self.x_ and self.y_ by the value of other.
342        ///
343        /// Arguments:
344        ///
345        /// * `other`: The parameter `other` is of type `T`, which means it can be any type that
346        ///             implements the `Clone` trait.
347        ///
348        /// # Example
349        ///
350        /// ```
351        /// use physdes::vector2::Vector2;
352        /// use std::ops::DivAssign;
353        ///
354        /// let mut v = Vector2::new(3, 6);
355        /// v.div_assign(3);
356        /// assert_eq!(v, Vector2::new(1, 2));
357        /// ```
358        fn div_assign(&mut self, other: T1) {
359            self.x_ /= other.clone();
360            self.y_ /= other;
361        }
362    }
363
364    macro_rules! forward_op_assign1 {
365        (impl $imp:ident, $method:ident) => {
366            impl<'a, T1: Clone + NumAssign, T2: Clone + NumAssign> $imp<&'a Vector2<T1, T2>>
367                for Vector2<T1, T2>
368            {
369                #[inline]
370                fn $method(&mut self, other: &Self) {
371                    self.$method(other.clone())
372                }
373            }
374        };
375    }
376
377    macro_rules! forward_op_assign2 {
378        (impl $imp:ident, $method:ident) => {
379            impl<'a, T1: Clone + NumAssign> $imp<&'a T1> for Vector2<T1, T1> {
380                #[inline]
381                fn $method(&mut self, other: &T1) {
382                    self.$method(other.clone())
383                }
384            }
385        };
386    }
387
388    forward_op_assign1!(impl AddAssign, add_assign);
389    forward_op_assign1!(impl SubAssign, sub_assign);
390    forward_op_assign2!(impl MulAssign, mul_assign);
391    forward_op_assign2!(impl DivAssign, div_assign);
392}
393
394impl<T1: Clone + Num + Neg<Output = T1>, T2: Clone + Num + Neg<Output = T2>> Neg
395    for Vector2<T1, T2>
396{
397    type Output = Self;
398
399    /// The `neg` function returns a new instance of the same type with the negated values of `x_` and
400    /// `y_`.
401    ///
402    /// # Example
403    ///
404    /// ```
405    /// use physdes::vector2::Vector2;
406    /// use std::ops::Neg;
407    ///
408    /// let v = Vector2::new(1, 2);
409    /// assert_eq!(-v, Vector2::new(-1, -2));
410    /// ```
411    #[inline]
412    fn neg(self) -> Self::Output {
413        Self::Output::new(-self.x_, -self.y_)
414    }
415}
416
417impl<T1: Clone + Num + Neg<Output = T1>, T2: Clone + Num + Neg<Output = T2>> Neg
418    for &Vector2<T1, T2>
419{
420    type Output = Vector2<T1, T2>;
421
422    #[inline]
423    fn neg(self) -> Self::Output {
424        -self.clone()
425    }
426}
427
428macro_rules! scalar_arithmetic {
429    (@forward $imp:ident::$method:ident for $($scalar:ident),*) => (
430        impl<'a, T1: Clone + Num> $imp<&'a T1> for Vector2<T1, T1> {
431            type Output = Vector2<T1, T1>;
432
433            #[inline]
434            fn $method(self, other: &T1) -> Self::Output {
435                self.$method(other.clone())
436            }
437        }
438        impl<'a, T1: Clone + Num> $imp<T1> for &'a Vector2<T1, T1> {
439            type Output = Vector2<T1, T1>;
440
441            #[inline]
442            fn $method(self, other: T1) -> Self::Output {
443                self.clone().$method(other)
444            }
445        }
446        impl<'a, 'b, T1: Clone + Num> $imp<&'a T1> for &'b Vector2<T1, T1> {
447            type Output = Vector2<T1, T1>;
448
449            #[inline]
450            fn $method(self, other: &T1) -> Self::Output {
451                self.clone().$method(other.clone())
452            }
453        }
454        $(
455            impl<'a> $imp<&'a Vector2<$scalar, $scalar>> for $scalar {
456                type Output = Vector2<$scalar, $scalar>;
457
458                #[inline]
459                fn $method(self, other: &Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
460                    self.$method(other.clone())
461                }
462            }
463            impl<'a> $imp<Vector2<$scalar, $scalar>> for &'a $scalar {
464                type Output = Vector2<$scalar, $scalar>;
465
466                #[inline]
467                fn $method(self, other: Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
468                    self.clone().$method(other)
469                }
470            }
471            impl<'a, 'b> $imp<&'a Vector2<$scalar, $scalar>> for &'b $scalar {
472                type Output = Vector2<$scalar, $scalar>;
473
474                #[inline]
475                fn $method(self, other: &Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
476                    self.clone().$method(other.clone())
477                }
478            }
479        )*
480    );
481    ($($scalar:ident),*) => (
482        scalar_arithmetic!(@forward Mul::mul for $($scalar),*);
483        // scalar_arithmetic!(@forward Div::div for $($scalar),*);
484        // scalar_arithmetic!(@forward Rem::rem for $($scalar),*);
485
486        $(
487            impl Mul<Vector2<$scalar, $scalar>> for $scalar {
488                type Output = Vector2<$scalar, $scalar>;
489
490                #[inline]
491                fn mul(self, other: Vector2<$scalar, $scalar>) -> Self::Output {
492                    Self::Output::new(self * other.x_, self * other.y_)
493                }
494            }
495
496        )*
497    );
498}
499
500impl<T1: Clone + Num> Mul<T1> for Vector2<T1, T1> {
501    type Output = Vector2<T1, T1>;
502
503    #[inline]
504    fn mul(self, other: T1) -> Self::Output {
505        Self::Output::new(self.x_ * other.clone(), self.y_ * other)
506    }
507}
508
509impl<T1: Clone + Num> Div<T1> for Vector2<T1, T1> {
510    type Output = Self;
511
512    #[inline]
513    fn div(self, other: T1) -> Self::Output {
514        Self::Output::new(self.x_ / other.clone(), self.y_ / other)
515    }
516}
517
518impl<T1: Clone + Num> Rem<T1> for Vector2<T1, T1> {
519    type Output = Vector2<T1, T1>;
520
521    #[inline]
522    fn rem(self, other: T1) -> Self::Output {
523        Self::Output::new(self.x_ % other.clone(), self.y_ % other)
524    }
525}
526
527scalar_arithmetic!(usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64);
528
529// constants
530impl<T1: Clone + Num + Add, T2: Clone + Num + Add> Zero for Vector2<T1, T2> {
531    #[inline]
532    fn zero() -> Self {
533        Self::new(Zero::zero(), Zero::zero())
534    }
535
536    #[inline]
537    fn is_zero(&self) -> bool {
538        self.x_.is_zero() && self.y_.is_zero()
539    }
540
541    #[inline]
542    fn set_zero(&mut self) {
543        self.x_.set_zero();
544        self.y_.set_zero();
545    }
546}
547
548#[cfg(test)]
549mod test {
550    #![allow(non_upper_case_globals)]
551
552    use super::Vector2;
553    use core::f64;
554    use num_traits::Zero;
555    use std::hash;
556
557    fn hash<T: hash::Hash>(x: &T) -> u64 {
558        use std::collections::hash_map::RandomState;
559        use std::hash::{BuildHasher, Hasher};
560        let mut hasher = <RandomState as BuildHasher>::Hasher::new();
561        x.hash(&mut hasher);
562        hasher.finish()
563    }
564
565    pub const _0_0v: Vector2<f64, f64> = Vector2 { x_: 0.0, y_: 0.0 };
566    pub const _1_0v: Vector2<f64, f64> = Vector2 { x_: 1.0, y_: 0.0 };
567    pub const _1_1v: Vector2<f64, f64> = Vector2 { x_: 1.0, y_: 1.0 };
568    pub const _0_1v: Vector2<f64, f64> = Vector2 { x_: 0.0, y_: 1.0 };
569    pub const _neg1_1v: Vector2<f64, f64> = Vector2 { x_: -1.0, y_: 1.0 };
570    pub const _05_05v: Vector2<f64, f64> = Vector2 { x_: 0.5, y_: 0.5 };
571    pub const all_consts: [Vector2<f64, f64>; 5] = [_0_0v, _1_0v, _1_1v, _neg1_1v, _05_05v];
572    pub const _4_2v: Vector2<f64, f64> = Vector2 { x_: 4.0, y_: 2.0 };
573
574    pub const _0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
575        x_: _0_0v,
576        y_: _0_0v,
577    };
578
579    // vector of vectors
580    pub const _0_0_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
581        x_: _0_0v,
582        y_: _0_0v,
583    };
584    pub const _1_0_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
585        x_: _1_0v,
586        y_: _0_0v,
587    };
588    pub const _1_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
589        x_: _1_1v,
590        y_: _0_0v,
591    };
592    pub const _0_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
593        x_: _0_1v,
594        y_: _0_0v,
595    };
596    pub const _neg1_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
597        x_: _neg1_1v,
598        y_: _0_0v,
599    };
600    pub const _05_05_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
601        x_: _05_05v,
602        y_: _0_0v,
603    };
604    pub const _0_0_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
605        x_: _0_0v,
606        y_: _1_0v,
607    };
608    pub const _1_0_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
609        x_: _1_0v,
610        y_: _1_0v,
611    };
612    pub const _1_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
613        x_: _1_1v,
614        y_: _1_0v,
615    };
616    pub const _0_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
617        x_: _0_1v,
618        y_: _1_0v,
619    };
620    pub const _neg1_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
621        x_: _neg1_1v,
622        y_: _1_0v,
623    };
624    pub const _05_05_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
625        x_: _05_05v,
626        y_: _1_0v,
627    };
628    pub const _0_0_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
629        x_: _0_0v,
630        y_: _0_1v,
631    };
632    pub const _1_0_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
633        x_: _1_0v,
634        y_: _0_1v,
635    };
636    pub const _1_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
637        x_: _1_1v,
638        y_: _0_1v,
639    };
640    pub const _0_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
641        x_: _0_1v,
642        y_: _0_1v,
643    };
644    pub const _neg1_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
645        x_: _neg1_1v,
646        y_: _0_1v,
647    };
648    pub const _05_05_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
649        x_: _05_05v,
650        y_: _0_1v,
651    };
652
653    #[test]
654    fn test_consts() {
655        // check our constants are what Vector2::new creates
656        fn test(c: Vector2<f64, f64>, r: f64, i: f64) {
657            assert_eq!(c, Vector2::new(r, i));
658        }
659        test(_0_0v, 0.0, 0.0);
660        test(_1_0v, 1.0, 0.0);
661        test(_1_1v, 1.0, 1.0);
662        test(_neg1_1v, -1.0, 1.0);
663        test(_05_05v, 0.5, 0.5);
664        assert_eq!(_0_0v, Zero::zero());
665    }
666
667    #[test]
668    fn test_scale_unscale() {
669        assert_eq!(_05_05v.scale(2.0), _1_1v);
670        assert_eq!(_1_1v.unscale(2.0), _05_05v);
671        for &c in all_consts.iter() {
672            assert_eq!(c.scale(2.0).unscale(2.0), c);
673        }
674    }
675
676    #[test]
677    fn test_hash() {
678        let a = Vector2::new(0i32, 0i32);
679        let b = Vector2::new(1i32, 0i32);
680        let c = Vector2::new(0i32, 1i32);
681        assert!(hash(&a) != hash(&b));
682        assert!(hash(&b) != hash(&c));
683        assert!(hash(&c) != hash(&a));
684    }
685
686    #[test]
687    fn test_zero() {
688        assert_eq!(_0_0v, Vector2::zero());
689    }
690
691    #[test]
692    fn test_is_zero() {
693        assert!(Vector2::<i32, i32>::zero().is_zero());
694        assert!(!_1_1v.is_zero());
695    }
696
697    #[test]
698    fn test_set_zero() {
699        let mut v = _1_1v;
700        v.set_zero();
701        assert!(v.is_zero());
702    }
703
704    #[test]
705    fn test_neg() {
706        assert_eq!(-(-_1_1v), _1_1v);
707    }
708
709    #[test]
710    fn test_scalar_arithmetic() {
711        assert_eq!(_1_1v * 0.5, _05_05v);
712        assert_eq!(_1_1v / 2.0, _05_05v);
713        assert_eq!(_4_2v % 2.0, _0_0v);
714        assert_eq!(0.5 * _1_1v, _05_05v);
715    }
716
717    #[test]
718    fn test_scalar_arithmetic_ref() {
719        assert_eq!(_1_1v * 0.5, _05_05v);
720        assert_eq!(0.5 * _1_1v, _05_05v);
721    }
722
723    #[test]
724    fn test_dot() {
725        assert_eq!(_1_1v.dot(&_1_1v), 2.0);
726        assert_eq!(_1_1v.dot(&_neg1_1v), 0.0);
727        assert_eq!(_1_1v.dot(&_0_1v), 1.0);
728    }
729
730    #[test]
731    fn test_cross() {
732        assert_eq!(_1_1v.cross(&_1_1v), 0.0);
733        assert_eq!(_1_1v.cross(&_neg1_1v), 2.0);
734        assert_eq!(_1_1v.cross(&_0_1v), 1.0);
735    }
736
737    // #[test]
738    // fn test_norm_sqr() {
739    //     assert_eq!(_1_1v.norm_sqr(), 2.0);
740    //     assert_eq!(_0_1v.norm_sqr(), 1.0);
741    //     assert_eq!(_neg1_1v.norm_sqr(), 2.0);
742    //     assert_eq!(_05_05v.norm_sqr(), 0.5);
743    //     assert_eq!(_1_0v.norm_sqr(), 1.0);
744    //     assert_eq!(_0_0v.norm_sqr(), 0.0);
745    //     assert_eq!(_4_2v.norm_sqr(), 20.0);
746    // }
747
748    #[test]
749    fn test_l1_norm() {
750        assert_eq!(_1_1v.l1_norm(), 2.0);
751        assert_eq!(_0_1v.l1_norm(), 1.0);
752        assert_eq!(_neg1_1v.l1_norm(), 2.0);
753        assert_eq!(_05_05v.l1_norm(), 1.0);
754        assert_eq!(_1_0v.l1_norm(), 1.0);
755        assert_eq!(_0_0v.l1_norm(), 0.0);
756        assert_eq!(_4_2v.l1_norm(), 6.0);
757    }
758
759    #[test]
760    fn test_norm_inf() {
761        assert_eq!(_1_1v.norm_inf(), 1.0);
762        assert_eq!(_0_1v.norm_inf(), 1.0);
763        assert_eq!(_neg1_1v.norm_inf(), 1.0);
764        assert_eq!(_05_05v.norm_inf(), 0.5);
765        assert_eq!(_1_0v.norm_inf(), 1.0);
766        assert_eq!(_0_0v.norm_inf(), 0.0);
767        assert_eq!(_4_2v.norm_inf(), 4.0);
768    }
769
770    #[test]
771    fn test_add_assign() {
772        let mut a = _0_1v;
773        a += _1_0v;
774        assert_eq!(a, _1_1v);
775    }
776
777    #[test]
778    fn test_sub_assign() {
779        let mut a = _1_1v;
780        a -= _1_1v;
781        assert_eq!(a, _0_0v);
782    }
783
784    #[test]
785    fn test_mul_assign() {
786        let mut a = _05_05v;
787        a *= 2.0;
788        assert_eq!(a, _1_1v);
789    }
790
791    #[test]
792    fn test_div_assign() {
793        let mut a = _1_1v;
794        a /= 2.0;
795        assert_eq!(a, _05_05v);
796    }
797
798    #[test]
799    fn test_rem() {
800        assert_eq!(_4_2v % 3.0, Vector2::new(1.0, 2.0));
801    }
802
803    #[test]
804    fn test_sub_more() {
805        assert_eq!(_1_1v - _0_1v, _1_0v);
806        assert_eq!(_0_1v - _1_0v, Vector2::new(-1.0, 1.0));
807    }
808
809    #[test]
810    fn test_add_more() {
811        assert_eq!(_1_0v + _0_1v, _1_1v);
812    }
813
814    #[test]
815    fn test_mul_more() {
816        assert_eq!(_1_1v * 2.0, Vector2::new(2.0, 2.0));
817    }
818
819    #[test]
820    fn test_dot_more_cases() {
821        assert_eq!(_0_0v.dot(&_1_1v), 0.0);
822        assert_eq!(_1_1v.dot(&_0_0v), 0.0);
823        assert_eq!(_neg1_1v.dot(&_1_1v), 0.0);
824    }
825
826    #[test]
827    fn test_cross_more_cases() {
828        assert_eq!(_0_0v.cross(&_1_1v), 0.0);
829        assert_eq!(_1_1v.cross(&_0_0v), 0.0);
830        assert_eq!(_neg1_1v.cross(&_1_1v), -2.0);
831    }
832
833    #[test]
834    fn test_l1_norm_more_cases() {
835        assert_eq!(_0_0v.l1_norm(), 0.0);
836        assert_eq!(_neg1_1v.l1_norm(), 2.0);
837    }
838
839    #[test]
840    fn test_norm_inf_more_cases() {
841        assert_eq!(_0_0v.norm_inf(), 0.0);
842        assert_eq!(_neg1_1v.norm_inf(), 1.0);
843    }
844
845    #[test]
846    fn test_scalar_arithmetic_more_cases() {
847        assert_eq!(_0_0v * 2.0, _0_0v);
848        assert_eq!(_1_1v * 0.0, _0_0v);
849        assert_eq!(_1_1v * 1.0, _1_1v);
850        assert_eq!(_1_1v * -1.0, -_1_1v);
851    }
852
853    #[test]
854    fn test_consts_vv() {
855        // check our constants are what Vector2::new creates
856        fn test(c: Vector2<Vector2<f64, f64>, Vector2<f64, f64>>, w: f64, x: f64, y: f64, z: f64) {
857            assert_eq!(c, Vector2::new(Vector2::new(w, x), Vector2::new(y, z)));
858        }
859
860        test(_0_0vv, 0.0, 0.0, 0.0, 0.0);
861        test(_0_0_0_0vv, 0.0, 0.0, 0.0, 0.0);
862        test(_1_0_0_0vv, 1.0, 0.0, 0.0, 0.0);
863        test(_1_1_0_0vv, 1.0, 1.0, 0.0, 0.0);
864        test(_0_1_0_0vv, 0.0, 1.0, 0.0, 0.0);
865        test(_neg1_1_0_0vv, -1.0, 1.0, 0.0, 0.0);
866        test(_05_05_0_0vv, 0.5, 0.5, 0.0, 0.0);
867        test(_0_0_1_0vv, 0.0, 0.0, 1.0, 0.0);
868        test(_1_0_1_0vv, 1.0, 0.0, 1.0, 0.0);
869        test(_1_1_1_0vv, 1.0, 1.0, 1.0, 0.0);
870        test(_0_1_1_0vv, 0.0, 1.0, 1.0, 0.0);
871        test(_neg1_1_1_0vv, -1.0, 1.0, 1.0, 0.0);
872        test(_05_05_1_0vv, 0.5, 0.5, 1.0, 0.0);
873    }
874
875    // #[test]
876    // fn test_scale_unscale_vv() {
877    //     assert_eq!(_05_05_0_0vv.scale(2.0), _1_1_0_0vv);
878    //     assert_eq!(_1_1_0_0vv.unscale(2.0), _05_05_0_0vv);
879    //     for &c in all_consts_vv.iter() {
880    //         assert_eq!(c.scale(2.0).unscale(2.0), c);
881    //     }
882    // }
883}