Skip to main content

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