ginger/
vector2.rs

1// #![no_std]
2use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
3use num_traits::{Num, Signed, Zero};
4
5/// The `Vector2` struct represents a 2-dimensional vector with elements of type `T`.
6///
7/// Properties:
8///
9/// * `x_`: The `x_` property represents the first element of the `Vector2` object. It is of type `T`,
10///         which means it can be any type that is specified when creating an instance of `Vector2`.
11/// * `y_`: The `y_` property is the second element of the `Vector2` object. It represents the
12///         y-coordinate of a 2D vector.
13///
14/// # Examples:
15///
16/// ```
17/// use ginger::vector2::Vector2;
18///
19/// assert_eq!(Vector2::new(3, 4), Vector2 { x_: 3, y_: 4});
20/// ```
21#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug, Default)]
22pub struct Vector2<T> {
23    /// The first element of the vector2 object
24    pub x_: T,
25    /// The second element of the vector2 object
26    pub y_: T,
27}
28
29impl<T> Vector2<T> {
30    /// Creates a new [`Vector2<T>`].
31    ///
32    /// The `new` function creates a new `Vector2` instance with the given `x` and `y` values.
33    ///
34    /// Arguments:
35    ///
36    /// * `x_`: The parameter `x_` represents the x-coordinate of the vector. It is of type `T`, which means
37    ///         it can be any type that implements the necessary operations for vector calculations (e.g., addition,
38    ///         subtraction, multiplication).
39    /// * `y_`: The `y_` parameter represents the y-coordinate of the vector.
40    ///
41    /// Returns:
42    ///
43    /// The `new` function returns a new instance of the `Vector2<T>` struct.
44    ///
45    /// # Examples
46    ///
47    /// ```
48    /// use ginger::vector2::Vector2;
49    ///
50    /// assert_eq!(Vector2::new(3, 4), Vector2 { x_: 3, y_: 4});
51    /// ```
52    #[inline]
53    pub const fn new(x_: T, y_: T) -> Self {
54        Vector2 { x_, y_ }
55    }
56}
57
58impl<T: Clone + Num> Vector2<T> {
59    /// The `dot` function calculates the dot product of two vectors.
60    ///
61    /// Arguments:
62    ///
63    /// * `other`: The `other` parameter is a reference to another `Vector2` object that we want to
64    ///            calculate the dot product with.
65    ///
66    /// Returns:
67    ///
68    /// The dot product of two vectors is being returned.
69    ///
70    /// # Examples
71    ///
72    /// ```
73    /// use ginger::vector2::Vector2;
74    ///
75    /// let vector2 = &Vector2::new(3, 4);
76    /// let other = &Vector2::new(5, 6);
77    /// assert_eq!(vector2.dot(other), 15 + 24);
78    /// assert_eq!(vector2.dot(&vector2), 9 + 16);
79    /// ```
80    #[inline]
81    pub fn dot(&self, other: &Self) -> T {
82        self.x_.clone() * other.x_.clone() + self.y_.clone() * other.y_.clone()
83    }
84
85    /// The `cross` function calculates the cross product of two vectors.
86    ///
87    /// Arguments:
88    ///
89    /// * `other`: The `other` parameter is a reference to another `Vector2` object that we want to
90    ///            calculate the cross product with.
91    ///
92    /// Returns:
93    ///
94    /// The cross product of two vectors is being returned.
95    ///
96    /// # Examples
97    ///
98    /// ```
99    /// use ginger::vector2::Vector2;
100    ///
101    /// let vector2 = &Vector2::new(3, 4);
102    /// let other = &Vector2::new(5, 6);
103    /// assert_eq!(vector2.cross(other), 18 - 20);
104    /// assert_eq!(vector2.cross(&vector2), 0);
105    /// ```
106    #[inline]
107    pub fn cross(&self, other: &Self) -> T {
108        self.x_.clone() * other.y_.clone() - self.y_.clone() * other.x_.clone()
109    }
110
111    /// Returns the norm sqr of this [`Vector2<T>`].
112    ///
113    /// The `norm_sqr` function calculates the squared norm of a `Vector2` object.
114    ///
115    /// Returns:
116    ///
117    /// The `norm_sqr` function returns the squared norm of the `Vector2<T>`.
118    ///
119    /// # Examples
120    ///
121    /// ```
122    /// use ginger::vector2::Vector2;
123    ///
124    /// let vector2 = &Vector2::new(3, 4);
125    /// assert_eq!(vector2.norm_sqr(), 9 + 16);
126    /// ```
127    #[inline]
128    pub fn norm_sqr(&self) -> T {
129        self.dot(self)
130    }
131
132    /// The `scale` function multiplies the x and y components of a `Vector2` object by a given scalar
133    /// value.
134    ///
135    /// Arguments:
136    ///
137    /// * `alpha`: The parameter `alpha` represents the scaling factor that will be applied to the vector.
138    ///
139    /// Returns:
140    ///
141    /// The `scale` method returns a new `Vector2` object.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// use ginger::vector2::Vector2;
147    ///
148    /// let vector2 = &Vector2::new(3.0, 4.0);
149    /// assert_eq!(vector2.scale(10.0), Vector2::new(30.0, 40.0));
150    /// assert_eq!(vector2.scale(0.5), Vector2::new(1.5, 2.0));
151    /// ```
152    #[inline]
153    pub fn scale(&self, alpha: T) -> Self {
154        Self::new(self.x_.clone() * alpha.clone(), self.y_.clone() * alpha)
155    }
156
157    /// The `unscale` function divides the x and y components of a `Vector2` by a given value.
158    ///
159    /// Arguments:
160    ///
161    /// * `alpha`: The `alpha` parameter is a value of type `T` that is used to divide the `x_` and `y_`
162    ///            values of the `Vector2` object.
163    ///
164    /// Returns:
165    ///
166    /// The `unscale` method returns a new `Vector2` object.
167    ///
168    /// # Examples
169    ///
170    /// ```
171    /// use ginger::vector2::Vector2;
172    ///
173    /// let vector2 = &Vector2::new(30, 40);
174    /// assert_eq!(vector2.unscale(10), Vector2::new(3, 4));
175    /// ```
176    #[inline]
177    pub fn unscale(&self, alpha: T) -> Self {
178        Self::new(self.x_.clone() / alpha.clone(), self.y_.clone() / alpha)
179    }
180}
181
182impl<T: Clone + Signed> Vector2<T> {
183    /// The `l1_norm` function calculates the Manhattan distance from the origin for a 2D vector.
184    ///
185    /// [Manhattan distance]: https://en.wikipedia.org/wiki/Taxicab_geometry
186    ///
187    /// Returns:
188    ///
189    /// The function `l1_norm` returns the L1 norm of a `Vector2` object, which is the sum of the absolute
190    /// values of its `x_` and `y_` components.
191    ///
192    /// # Examples
193    ///
194    /// ```
195    /// use ginger::vector2::Vector2;
196    ///
197    /// let vector2 = &Vector2::new(3, -4);
198    /// assert_eq!(vector2.l1_norm(), 7);
199    /// ```
200    #[inline]
201    pub fn l1_norm(&self) -> T {
202        self.x_.abs() + self.y_.abs()
203    }
204}
205
206impl<T: Clone + PartialOrd> Vector2<T> {
207    /// The `norm_inf` function returns the maximum absolute value of the two elements in a `Vector2`
208    /// object.
209    ///
210    /// Returns:
211    ///
212    /// The `norm_inf` function returns the maximum value between `self.x_` and `self.y_`.
213    ///
214    /// # Examples
215    ///
216    /// ```
217    /// use ginger::vector2::Vector2;
218    ///
219    /// let vector2 = &Vector2::new(3, -4);
220    /// assert_eq!(vector2.norm_inf(), 3);
221    /// ```
222    #[inline]
223    pub fn norm_inf(&self) -> T {
224        if self.x_ > self.y_ {
225            self.x_.clone()
226        } else {
227            self.y_.clone()
228        }
229    }
230}
231
232macro_rules! forward_xf_xf_binop {
233    (impl $imp:ident, $method:ident) => {
234        impl<'a, 'b, T: Clone + Num> $imp<&'b Vector2<T>> for &'a Vector2<T> {
235            type Output = Vector2<T>;
236
237            #[inline]
238            fn $method(self, other: &Vector2<T>) -> Self::Output {
239                self.clone().$method(other.clone())
240            }
241        }
242    };
243}
244
245macro_rules! forward_xf_val_binop {
246    (impl $imp:ident, $method:ident) => {
247        impl<'a, T: Clone + Num> $imp<Vector2<T>> for &'a Vector2<T> {
248            type Output = Vector2<T>;
249
250            #[inline]
251            fn $method(self, other: Vector2<T>) -> Self::Output {
252                self.clone().$method(other)
253            }
254        }
255    };
256}
257
258macro_rules! forward_val_xf_binop {
259    (impl $imp:ident, $method:ident) => {
260        impl<'a, T: Clone + Num> $imp<&'a Vector2<T>> for Vector2<T> {
261            type Output = Vector2<T>;
262
263            #[inline]
264            fn $method(self, other: &Vector2<T>) -> Self::Output {
265                self.$method(other.clone())
266            }
267        }
268    };
269}
270
271macro_rules! forward_all_binop {
272    (impl $imp:ident, $method:ident) => {
273        forward_xf_xf_binop!(impl $imp, $method);
274        forward_xf_val_binop!(impl $imp, $method);
275        forward_val_xf_binop!(impl $imp, $method);
276    };
277}
278
279// arithmetic
280forward_all_binop!(impl Add, add);
281
282// (a, b) + (c, d) == (a + c), (b + d)
283impl<T: Clone + Num> Add<Vector2<T>> for Vector2<T> {
284    type Output = Self;
285
286    #[inline]
287    fn add(self, other: Self) -> Self::Output {
288        Self::Output::new(self.x_ + other.x_, self.y_ + other.y_)
289    }
290}
291
292forward_all_binop!(impl Sub, sub);
293
294// (a, b) - (c, d) == (a - c), (b - d)
295impl<T: Clone + Num> Sub<Vector2<T>> for Vector2<T> {
296    type Output = Self;
297
298    #[inline]
299    fn sub(self, other: Self) -> Self::Output {
300        Self::Output::new(self.x_ - other.x_, self.y_ - other.y_)
301    }
302}
303
304// Op Assign
305
306mod opassign {
307    use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
308
309    use num_traits::NumAssign;
310
311    use crate::Vector2;
312
313    impl<T: Clone + NumAssign> AddAssign for Vector2<T> {
314        fn add_assign(&mut self, other: Self) {
315            self.x_ += other.x_;
316            self.y_ += other.y_;
317        }
318    }
319
320    impl<T: Clone + NumAssign> SubAssign for Vector2<T> {
321        fn sub_assign(&mut self, other: Self) {
322            self.x_ -= other.x_;
323            self.y_ -= other.y_;
324        }
325    }
326
327    impl<T: Clone + NumAssign> MulAssign<T> for Vector2<T> {
328        fn mul_assign(&mut self, other: T) {
329            self.x_ *= other.clone();
330            self.y_ *= other;
331        }
332    }
333
334    impl<T: Clone + NumAssign> DivAssign<T> for Vector2<T> {
335        fn div_assign(&mut self, other: T) {
336            self.x_ /= other.clone();
337            self.y_ /= other;
338        }
339    }
340
341    macro_rules! forward_op_assign1 {
342        (impl $imp:ident, $method:ident) => {
343            impl<'a, T: Clone + NumAssign> $imp<&'a Vector2<T>> for Vector2<T> {
344                #[inline]
345                fn $method(&mut self, other: &Self) {
346                    self.$method(other.clone())
347                }
348            }
349        };
350    }
351
352    macro_rules! forward_op_assign2 {
353        (impl $imp:ident, $method:ident) => {
354            impl<'a, T: Clone + NumAssign> $imp<&'a T> for Vector2<T> {
355                #[inline]
356                fn $method(&mut self, other: &T) {
357                    self.$method(other.clone())
358                }
359            }
360        };
361    }
362
363    forward_op_assign1!(impl AddAssign, add_assign);
364    forward_op_assign1!(impl SubAssign, sub_assign);
365    forward_op_assign2!(impl MulAssign, mul_assign);
366    forward_op_assign2!(impl DivAssign, div_assign);
367}
368
369impl<T: Clone + Num + Neg<Output = T>> Neg for Vector2<T> {
370    type Output = Self;
371
372    #[inline]
373    fn neg(self) -> Self::Output {
374        Self::Output::new(-self.x_, -self.y_)
375    }
376}
377
378impl<T: Clone + Num + Neg<Output = T>> Neg for &Vector2<T> {
379    type Output = Vector2<T>;
380
381    #[inline]
382    fn neg(self) -> Self::Output {
383        -self.clone()
384    }
385}
386
387macro_rules! scalar_arithmetic {
388    (@forward $imp:ident::$method:ident for $($scalar:ident),*) => (
389        impl<'a, T: Clone + Num> $imp<&'a T> for Vector2<T> {
390            type Output = Vector2<T>;
391
392            #[inline]
393            fn $method(self, other: &T) -> Self::Output {
394                self.$method(other.clone())
395            }
396        }
397        impl<'a, T: Clone + Num> $imp<T> for &'a Vector2<T> {
398            type Output = Vector2<T>;
399
400            #[inline]
401            fn $method(self, other: T) -> Self::Output {
402                self.clone().$method(other)
403            }
404        }
405        impl<'a, 'b, T: Clone + Num> $imp<&'a T> for &'b Vector2<T> {
406            type Output = Vector2<T>;
407
408            #[inline]
409            fn $method(self, other: &T) -> Self::Output {
410                self.clone().$method(other.clone())
411            }
412        }
413        $(
414            impl<'a> $imp<&'a Vector2<$scalar>> for $scalar {
415                type Output = Vector2<$scalar>;
416
417                #[inline]
418                fn $method(self, other: &Vector2<$scalar>) -> Vector2<$scalar> {
419                    self.$method(other.clone())
420                }
421            }
422            impl<'a> $imp<Vector2<$scalar>> for &'a $scalar {
423                type Output = Vector2<$scalar>;
424
425                #[inline]
426                fn $method(self, other: Vector2<$scalar>) -> Vector2<$scalar> {
427                    self.clone().$method(other)
428                }
429            }
430            impl<'a, 'b> $imp<&'a Vector2<$scalar>> for &'b $scalar {
431                type Output = Vector2<$scalar>;
432
433                #[inline]
434                fn $method(self, other: &Vector2<$scalar>) -> Vector2<$scalar> {
435                    self.clone().$method(other.clone())
436                }
437            }
438        )*
439    );
440    ($($scalar:ident),*) => (
441        scalar_arithmetic!(@forward Mul::mul for $($scalar),*);
442        // scalar_arithmetic!(@forward Div::div for $($scalar),*);
443        // scalar_arithmetic!(@forward Rem::rem for $($scalar),*);
444
445        $(
446            impl Mul<Vector2<$scalar>> for $scalar {
447                type Output = Vector2<$scalar>;
448
449                #[inline]
450                fn mul(self, other: Vector2<$scalar>) -> Self::Output {
451                    Self::Output::new(self * other.x_, self * other.y_)
452                }
453            }
454
455        )*
456    );
457}
458
459impl<T: Clone + Num> Mul<T> for Vector2<T> {
460    type Output = Vector2<T>;
461
462    #[inline]
463    fn mul(self, other: T) -> Self::Output {
464        Self::Output::new(self.x_ * other.clone(), self.y_ * other)
465    }
466}
467
468impl<T: Clone + Num> Div<T> for Vector2<T> {
469    type Output = Self;
470
471    #[inline]
472    fn div(self, other: T) -> Self::Output {
473        Self::Output::new(self.x_ / other.clone(), self.y_ / other)
474    }
475}
476
477impl<T: Clone + Num> Rem<T> for Vector2<T> {
478    type Output = Vector2<T>;
479
480    #[inline]
481    fn rem(self, other: T) -> Self::Output {
482        Self::Output::new(self.x_ % other.clone(), self.y_ % other)
483    }
484}
485
486scalar_arithmetic!(usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64);
487
488// constants
489impl<T: Clone + Num> Zero for Vector2<T> {
490    #[inline]
491    fn zero() -> Self {
492        Self::new(Zero::zero(), Zero::zero())
493    }
494
495    #[inline]
496    fn is_zero(&self) -> bool {
497        self.x_.is_zero() && self.y_.is_zero()
498    }
499
500    #[inline]
501    fn set_zero(&mut self) {
502        self.x_.set_zero();
503        self.y_.set_zero();
504    }
505}
506
507// #[cfg(test)]
508// fn hash<T: hash::Hash>(x: &T) -> u64 {
509//     use std::collections::hash_map::RandomState;
510//     use std::hash::{BuildHasher, Hasher};
511//     let mut hasher = <RandomState as BuildHasher>::Hasher::new();
512//     x.hash(&mut hasher);
513//     hasher.finish()
514// }
515
516#[cfg(test)]
517mod test {
518    #![allow(non_upper_case_globals)]
519
520    // use super::{hash, Vector2};
521    use super::Vector2;
522    use core::f64;
523    use num_traits::Zero;
524
525    pub const _0_0v: Vector2<f64> = Vector2 { x_: 0.0, y_: 0.0 };
526    pub const _1_0v: Vector2<f64> = Vector2 { x_: 1.0, y_: 0.0 };
527    pub const _1_1v: Vector2<f64> = Vector2 { x_: 1.0, y_: 1.0 };
528    pub const _0_1v: Vector2<f64> = Vector2 { x_: 0.0, y_: 1.0 };
529    pub const _neg1_1v: Vector2<f64> = Vector2 { x_: -1.0, y_: 1.0 };
530    pub const _05_05v: Vector2<f64> = Vector2 { x_: 0.5, y_: 0.5 };
531    pub const all_consts: [Vector2<f64>; 5] = [_0_0v, _1_0v, _1_1v, _neg1_1v, _05_05v];
532    pub const _4_2v: Vector2<f64> = Vector2 { x_: 4.0, y_: 2.0 };
533
534    #[test]
535    fn test_consts() {
536        // check our constants are what Vector2::new creates
537        fn test(c: Vector2<f64>, r: f64, i: f64) {
538            assert_eq!(c, Vector2::new(r, i));
539        }
540        test(_0_0v, 0.0, 0.0);
541        test(_1_0v, 1.0, 0.0);
542        test(_1_1v, 1.0, 1.0);
543        test(_neg1_1v, -1.0, 1.0);
544        test(_05_05v, 0.5, 0.5);
545        assert_eq!(_0_0v, Zero::zero());
546    }
547
548    #[test]
549    fn test_scale_unscale() {
550        assert_eq!(_05_05v.scale(2.0), _1_1v);
551        assert_eq!(_1_1v.unscale(2.0), _05_05v);
552        for &c in all_consts.iter() {
553            assert_eq!(c.scale(2.0).unscale(2.0), c);
554        }
555    }
556
557    // #[test]
558    // fn test_hash() {
559    //     let a = Vector2::new(0i32, 0i32);
560    //     let b = Vector2::new(1i32, 0i32);
561    //     let c = Vector2::new(0i32, 1i32);
562    //     assert!(hash(&a) != hash(&b));
563    //     assert!(hash(&b) != hash(&c));
564    //     assert!(hash(&c) != hash(&a));
565    // }
566
567    #[test]
568    fn test_new() {
569        let v = Vector2::new(1, 2);
570        assert_eq!(v.x_, 1);
571        assert_eq!(v.y_, 2);
572    }
573
574    #[test]
575    fn test_dot() {
576        let v1 = Vector2::new(3, 4);
577        let v2 = Vector2::new(5, 6);
578        assert_eq!(v1.dot(&v2), 3 * 5 + 4 * 6);
579        assert_eq!(v1.dot(&v1), 3 * 3 + 4 * 4);
580    }
581
582    #[test]
583    fn test_cross() {
584        let v1 = Vector2::new(3, 4);
585        let v2 = Vector2::new(5, 6);
586        assert_eq!(v1.cross(&v2), 3 * 6 - 4 * 5);
587        assert_eq!(v1.cross(&v1), 0);
588    }
589
590    #[test]
591    fn test_norm_sqr() {
592        let v = Vector2::new(3, 4);
593        assert_eq!(v.norm_sqr(), 9 + 16);
594    }
595
596    #[test]
597    fn test_scale() {
598        let v = Vector2::new(3.0, 4.0);
599        assert_eq!(v.scale(2.0), Vector2::new(6.0, 8.0));
600        assert_eq!(v.scale(0.5), Vector2::new(1.5, 2.0));
601    }
602
603    #[test]
604    fn test_unscale() {
605        let v = Vector2::new(30, 40);
606        assert_eq!(v.unscale(10), Vector2::new(3, 4));
607    }
608
609    #[test]
610    fn test_l1_norm() {
611        let v = Vector2::new(3, -4);
612        assert_eq!(v.l1_norm(), 7);
613    }
614
615    #[test]
616    fn test_norm_inf() {
617        let v1 = Vector2::new(3, -4);
618        assert_eq!(v1.norm_inf(), 3);
619
620        let v2 = Vector2::new(5, 2);
621        assert_eq!(v2.norm_inf(), 5);
622    }
623
624    #[test]
625    fn test_add() {
626        let v1 = Vector2::new(1, 2);
627        let v2 = Vector2::new(3, 4);
628        assert_eq!(v1 + v2, Vector2::new(4, 6));
629
630        let v3 = v1 + v2;
631        assert_eq!(v3, Vector2::new(4, 6));
632
633        let v4 = v1 + &v2;
634        assert_eq!(v4, Vector2::new(4, 6));
635    }
636
637    #[test]
638    fn test_sub() {
639        let v1 = Vector2::new(5, 6);
640        let v2 = Vector2::new(3, 4);
641        assert_eq!(v1 - v2, Vector2::new(2, 2));
642
643        let v3 = v1 - v2;
644        assert_eq!(v3, Vector2::new(2, 2));
645    }
646
647    #[test]
648    fn test_neg() {
649        let v = Vector2::new(1, -2);
650        assert_eq!(-v, Vector2::new(-1, 2));
651        assert_eq!(-&v, Vector2::new(-1, 2));
652    }
653
654    #[test]
655    fn test_scalar_mul() {
656        let v = Vector2::new(2, 3);
657        assert_eq!(v * 4, Vector2::new(8, 12));
658        assert_eq!(&v * 4, Vector2::new(8, 12));
659        assert_eq!(4 * v, Vector2::new(8, 12));
660        assert_eq!(4 * &v, Vector2::new(8, 12));
661    }
662
663    #[test]
664    fn test_scalar_div() {
665        let v = Vector2::new(10, 20);
666        assert_eq!(v / 5, Vector2::new(2, 4));
667    }
668
669    #[test]
670    fn test_scalar_rem() {
671        let v = Vector2::new(10, 21);
672        assert_eq!(v % 3, Vector2::new(1, 0));
673    }
674
675    #[test]
676    fn test_zero() {
677        let zero = Vector2::<i32>::zero();
678        assert_eq!(zero, Vector2::new(0, 0));
679        assert!(zero.is_zero());
680
681        let mut v = Vector2::new(1, 2);
682        assert!(!v.is_zero());
683        v.set_zero();
684        assert!(v.is_zero());
685    }
686
687    #[test]
688    fn test_add_assign() {
689        let mut v1 = Vector2::new(1, 2);
690        let v2 = Vector2::new(3, 4);
691        v1 += v2;
692        assert_eq!(v1, Vector2::new(4, 6));
693
694        let mut v3 = Vector2::new(1, 2);
695        v3 += &v2;
696        assert_eq!(v3, Vector2::new(4, 6));
697    }
698
699    #[test]
700    fn test_sub_assign() {
701        let mut v1 = Vector2::new(5, 6);
702        let v2 = Vector2::new(3, 4);
703        v1 -= v2;
704        assert_eq!(v1, Vector2::new(2, 2));
705
706        let mut v3 = Vector2::new(5, 6);
707        v3 -= &v2;
708        assert_eq!(v3, Vector2::new(2, 2));
709    }
710
711    #[test]
712    fn test_mul_assign() {
713        let mut v = Vector2::new(1, 2);
714        v *= 3;
715        assert_eq!(v, Vector2::new(3, 6));
716
717        let mut v2 = Vector2::new(1, 2);
718        let scalar = 3;
719        v2 *= &scalar;
720        assert_eq!(v2, Vector2::new(3, 6));
721    }
722
723    #[test]
724    fn test_div_assign() {
725        let mut v = Vector2::new(6, 9);
726        v /= 3;
727        assert_eq!(v, Vector2::new(2, 3));
728
729        let mut v2 = Vector2::new(6, 9);
730        let scalar = 3;
731        v2 /= &scalar;
732        assert_eq!(v2, Vector2::new(2, 3));
733    }
734
735    #[test]
736    fn test_float_operations() {
737        let v = Vector2::new(1.5, 2.5);
738        assert_eq!(v.scale(2.0), Vector2::new(3.0, 5.0));
739        assert_eq!(v.unscale(0.5), Vector2::new(3.0, 5.0));
740        assert_eq!(v.dot(&v), 1.5 * 1.5 + 2.5 * 2.5);
741    }
742
743    #[test]
744    fn test_clone_and_eq() {
745        let v1 = Vector2::new(1, 2);
746        let v2 = v1;
747        assert_eq!(v1, v2);
748
749        let v3 = Vector2::new(2, 1);
750        assert_ne!(v1, v3);
751    }
752
753    #[test]
754    fn test_debug() {
755        let v = Vector2::new(1, 2);
756        assert_eq!(format!("{:?}", v), "Vector2 { x_: 1, y_: 2 }");
757    }
758}