vector2d/
lib.rs

1//! # vector2d
2//! A simple and convenient 2D vector library without excessive use of external
3//! dependencies. If other vector crates are swiss-army knives, vector2d is a
4//! spoon; safe, intuitive, and convenient. As an added bonus, you won't run
5//! into any excursions with the law using this library thanks to the awfully
6//! permissive Unlicense.
7//!
8//! The only type in this crate is [`Vector2D`], which is highly generic;
9//! shifting functionality depending upon the traits implemented by its internal
10//! components' types.
11//!
12//! [`Vector2D`]: struct.Vector2D.html
13//!
14//! # Example
15//! ```
16//! use vector2d::Vector2D;
17//!
18//! // Vectors have fields X and Y, these can be of any type
19//! let v1: Vector2D<i32> = Vector2D { x: 10, y: 5 };
20//!
21//! // Alternatively you can use new(..) to condense instantiation
22//! let v2: Vector2D<f64> = Vector2D::new(13.0, 11.5);
23//!
24//! // There are two ways to cast between Vector2Ds, depending on the source
25//! // and target types.
26//! //
27//! // If the target type has a implementation of From<SourceType>, then you
28//! // can either use source.into_vec2d() or Vector2D::from_vec2d(source).
29//! assert_eq!(Vector2D::new(10.0, 5.0), v1.into_vec2d());
30//! assert_eq!(Vector2D::new(10.0, 5.0), Vector2D::from_vec2d(v1));
31//!
32//! // If there is no From or Into implementation, then you're out of luck
33//! // unless you are using specific primitives, such as i32 and f64. In
34//! // this case you can use specialised functions, as shown below:
35//! assert_eq!(Vector2D::new(13, 11), v2.as_i32s());
36//!
37//! // The full list of interoperable primitives is as follows:
38//! //   - i32, i64, isize
39//! //   - u32, u64, usize
40//! //   - f32, f64
41//!
42//! // As primitives generally implement From/Into for lossless casts,
43//! // an as_Ts() function is not available for those types, and
44//! // from(..)/into() should be favoured.
45//! //
46//! // Casts between signed and unsigned primitives will perform bounds
47//! // checking, so casting the vector (-10.0, 2.0) to a Vector2D<u32> will
48//! // result in the vector (0, 2).
49//!
50//! // For types with an Add and Mul implementation, the functions dot() and
51//! // length_squared() are available. For access to length(), normalise(),
52//! // or angle() however, you must be using either Vector2D<f32> or
53//! // Vector2D<f64>.
54//! let _v1_len_sq = v1.length_squared();
55//! let v2_len = v2.length();
56//! let v2_dir = v2.normalise();
57//!
58//! // Assuming the operator traits are implemented for the types involved,
59//! // you can add and subtract Vector2Ds from one-another, as well as
60//! // multiply and divide them with scalar values.
61//! assert_eq!(v2, v2_dir * v2_len);
62//! assert_eq!(Vector2D::new(23.0, 16.5),  v2 + v1.into_vec2d()) ;
63//!
64//! // If you feel the need to multiply or divide individual components of
65//! // vectors with the same type, you can use mul_components(...) or
66//! // div_components(...) provided that their types can be multiplied or
67//! // divided.
68//!
69//! // For any Vector2D<T>, there is an implementation of
70//! // From<(T, T)> and From<[T; 2]>
71//! let v4: Vector2D<f64> = Vector2D::new(1.5, 2.3);
72//! assert_eq!(v4, (1.5, 2.3).into());
73//! assert_eq!(v4, [1.5, 2.3].into());
74//!
75//! // Additionally, there is an Into<(T, T)> implementation for any types
76//! // that the vector components have their own Into implementations for
77//! assert_eq!((1.5, 2.3), v4.into());
78//!
79//! // If you want the normal of a vector you can just call normal()
80//! let v5 = Vector2D::new(-10.0, -2.3);
81//! assert_eq!(Vector2D::new(2.3, -10.0), v5.normal());
82//!
83//! // You can get a vector consisting of only the horizontal or vertical
84//! // component of a vector by calling horizontal() or vertical()
85//! // respectively
86//! let v6 = Vector2D::new(12.3, 83.2);
87//! assert_eq!(Vector2D::new(12.3, 0.0), v6.horizontal());
88//! assert_eq!(Vector2D::new(0.0, 83.2), v6.vertical());
89//! ```
90
91#[cfg(test)]
92mod test;
93
94use std::cmp::Ordering;
95use std::ops::{
96    Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
97};
98
99/// Convenience macro for implementing funcs like `as_i32s` concisely
100macro_rules! fn_simple_as {
101    ($func:ident, $type:ty) => {
102        pub fn $func(&self) -> Vector2D<$type> {
103            Vector2D {
104                x: self.x as $type,
105                y: self.y as $type,
106            }
107        }
108    };
109}
110
111/// Convenience macro for implementing funcs like `as_u32s` concisely, while appropriately setting
112/// a lower bound (e.g. 0.0) for the source value before the conversion is performed
113macro_rules! fn_lower_bounded_as {
114    ($func:ident, $dst_type:ty, $lower_bound:expr) => {
115        pub fn $func(&self) -> Vector2D<$dst_type> {
116            Vector2D {
117                x: self.x.max($lower_bound) as $dst_type,
118                y: self.y.max($lower_bound) as $dst_type,
119            }
120        }
121    };
122}
123
124/// Convenience macro for implementing funcs like `as i32s` concisely, while appropriately setting
125/// bounds (e.g. from i32::MIN to i32::MAX) for the source value before the conversion is
126/// performed
127macro_rules! fn_bounded_as {
128    ($func:ident, $dst_type:ty, $lower_bound:expr, $upper_bound:expr) => {
129        pub fn $func(&self) -> Vector2D<$dst_type> {
130            Vector2D {
131                x: self.x.min($upper_bound).max($lower_bound) as $dst_type,
132                y: self.y.min($upper_bound).max($lower_bound) as $dst_type,
133            }
134        }
135    };
136}
137
138/// A 2D vector, containing an `x` and a `y` component. While many types can be
139/// used for a `Vector2D`'s components, the traits they implement determine
140/// what functions are available.
141///
142/// Provided that the components implement the necessary traits, `Vector2D`s
143/// can be added to or subtracted from one-another, and they can be mulitplied
144/// and divided by scalar values.
145///
146/// There are generally two options for converting between `Vector2D` types. If
147/// the internal components' type has an implementation of `Into` that targets
148/// the desired type, then [`into_vec2d()`] can be called from the source object,
149/// or [`from_vec2d(..)`] can be called and the source object can be provided.
150///
151/// If no `Into` implementation exists, then the only option is to use one of the
152/// flavours of casting with `as`. These are in the form `as_types()`, and are only
153/// implemented for specific types of components. An example usage would look like
154/// this:
155/// ```
156/// use vector2d::Vector2D;
157/// let f64_vector: Vector2D<f64> = Vector2D::new(10.3, 11.1);
158/// let i32_vector: Vector2D<i32> = f64_vector.as_i32s();
159/// assert_eq!(Vector2D::new(10, 11), i32_vector);
160/// ```
161///
162/// Implementations of `as_types()` are only available when an implementation of
163/// [`into_vec2d()`] is unavailable. This is to seperate between the lossless casting
164/// of primitives with `into()` and `from(..)`, and the lossy casting between
165/// primitives of varying detail.
166///
167/// Casts from signed types to unsigned types have a small additional check that
168/// ensures a lower bound of 0 on the signed value, to reduce the chances of
169/// experiencing undefined behaviour. This means that a `Vector2D<f64>` with a
170/// value of `(-10.3, 11.1)` would become `(0, 11)` when cast to a `Vector2D<u32>`
171/// with [`as_u32s()`].
172///
173/// The current list of interoperable types that can be cast with the `as` family of
174/// functions is as follows:
175///   - `i32`
176///   - `i64`,
177///   - `isize`
178///   - `u32`
179///   - `u64`
180///   - `usize`
181///   - `f32`
182///   - `f64`
183///
184/// [`into_vec2d()`]: struct.Vector2D.html#method.into_vec2d
185/// [`from_vec2d(..)`]: struct.Vector2D.html#method.from_vec2d
186/// [`as_u32s()`]: struct.Vector2D.html#method.as_u32s-1
187#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
188pub struct Vector2D<T> {
189    pub x: T,
190    pub y: T,
191}
192
193impl<T: Copy + Clone> Vector2D<T> {
194    /// Create a new `Vector2D` with the provided components.
195    pub const fn new(x: T, y: T) -> Self {
196        Self { x, y }
197    }
198
199    /// Convert a `Vector2` of type `U` to one of type `T`. Available only when
200    /// type T has implemented `From<U>`.
201    ///
202    /// # Example
203    /// ```
204    /// use vector2d::Vector2D;
205    /// let i32_vector: Vector2D<i32> = Vector2D::new(25, 8);
206    /// let f64_vector: Vector2D<f64> = Vector2D::from_vec2d(i32_vector);
207    /// assert_eq!(Vector2D::new(25.0, 8.0), f64_vector);
208    /// ```
209    pub fn from_vec2d<U: Into<T> + Copy + Clone>(src: Vector2D<U>) -> Vector2D<T> {
210        Vector2D {
211            x: src.x.into(),
212            y: src.y.into(),
213        }
214    }
215
216    /// Convert a `Vector2` of type `T` to one of type `U`. Available only when
217    /// type T has implemented `Into<U>`.
218    ///
219    /// # Example
220    /// ```
221    /// use vector2d::Vector2D;
222    /// let i32_vector: Vector2D<i32> = Vector2D::new(25, 8);
223    /// let i32_vector: Vector2D<i32> = Vector2D::new(25, 8);
224    /// let f64_vector: Vector2D<f64> = i32_vector.into_vec2d();
225    /// assert_eq!(Vector2D::new(25.0, 8.0), f64_vector);
226    /// ```
227    pub fn into_vec2d<U: From<T>>(self) -> Vector2D<U> {
228        Vector2D {
229            x: self.x.into(),
230            y: self.y.into(),
231        }
232    }
233}
234
235impl<T> Default for Vector2D<T>
236where
237    T: Default,
238{
239    fn default() -> Self {
240        Self {
241            x: T::default(),
242            y: T::default(),
243        }
244    }
245}
246
247impl<T: Default> Vector2D<T> {
248    /// Returns a vector with only the horizontal component of the current one
249    ///
250    /// # Example
251    /// ```
252    /// use vector2d::Vector2D;
253    /// let v = Vector2D::new(10, 20);
254    /// assert_eq!(Vector2D::new(10, 0), v.horizontal());
255    /// ```
256    pub fn horizontal(self) -> Self {
257        Self {
258            x: self.x,
259            y: Default::default(),
260        }
261    }
262
263    /// Returns a vector with only the vertical component of the current one
264    ///
265    /// # Example
266    /// ```
267    /// use vector2d::Vector2D;
268    /// let v = Vector2D::new(10, 20);
269    /// assert_eq!(Vector2D::new(0, 20), v.vertical());
270    pub fn vertical(self) -> Self {
271        Self {
272            x: Default::default(),
273            y: self.y,
274        }
275    }
276}
277
278impl<T> Vector2D<T>
279where
280    T: Mul<T, Output = T> + Copy + Clone,
281{
282    /// Returns a new vector with components equal to each of the current vector's
283    /// components multiplied by the corresponding component of the provided vector
284    ///
285    /// # Example
286    /// ```
287    /// use vector2d::Vector2D;
288    /// let v1 = Vector2D::new(11.0, -2.5);
289    /// let v2 = Vector2D::new(0.5, -2.0);
290    /// assert_eq!(Vector2D::new(5.5, 5.0), v1.mul_components(v2));
291    /// ```
292    pub fn mul_components(self, other: Self) -> Self {
293        Self {
294            x: self.x * other.x,
295            y: self.y * other.y,
296        }
297    }
298}
299
300impl<T> Vector2D<T>
301where
302    T: Div<T, Output = T> + Copy + Clone,
303{
304    /// Returns a new vector with components equal to each of the current vector's
305    /// components divided by the corresponding component of the provided vector
306    ///
307    /// # Example
308    /// ```
309    /// use vector2d::Vector2D;
310    /// let v1 = Vector2D::new(11.0, -2.5);
311    /// let v2 = Vector2D::new(0.5, -2.0);
312    /// assert_eq!(Vector2D::new(22.0, 1.25), v1.div_components(v2));
313    /// ```
314    pub fn div_components(self, other: Self) -> Self {
315        Self {
316            x: self.x / other.x,
317            y: self.y / other.y,
318        }
319    }
320}
321
322impl<T, U> Neg for Vector2D<T>
323where
324    T: Neg<Output = U> + Copy + Clone,
325{
326    type Output = Vector2D<U>;
327    fn neg(self) -> Self::Output {
328        Self::Output {
329            x: -self.x,
330            y: -self.y,
331        }
332    }
333}
334
335impl<T> Vector2D<T>
336where
337    T: Neg<Output = T> + Copy + Clone,
338{
339    /// Returns a vector perpendicular to the current one.
340    ///
341    /// # Example
342    /// ```
343    /// use vector2d::Vector2D;
344    /// let v = Vector2D::new(21.3, -98.1);
345    /// assert_eq!(Vector2D::new(98.1, 21.3), v.normal());
346    /// ```
347    pub fn normal(self) -> Self {
348        Self {
349            x: -self.y,
350            y: self.x,
351        }
352    }
353}
354
355impl<T, U, V> Vector2D<T>
356where
357    T: Mul<T, Output = U> + Copy + Clone,
358    U: Add<U, Output = V> + Copy + Clone,
359{
360    /// Get the scalar/dot product of the two `Vector2D`.
361    pub fn dot(v1: Self, v2: Self) -> V {
362        v1.x * v2.x + v1.y * v2.y
363    }
364
365    /// Get the squared length of a `Vector2D`. This is more performant than using
366    /// `length()` -- which is only available for `Vector2D<f32>` and `Vector2D<f64>`
367    /// -- as it does not perform any square root operation.
368    pub fn length_squared(self) -> V {
369        self.x * self.x + self.y * self.y
370    }
371}
372
373impl<T> Vector2D<T>
374where
375    T: Sub<T, Output = T> + Mul<T, Output = T> + Add<T, Output = T> + Copy + Clone,
376{
377    /// Linearly interpolates between two vectors
378    pub fn lerp(start: Self, end: Self, progress: T) -> Self {
379        start + ((end - start) * progress)
380    }
381}
382
383// From/Into Implementations
384
385impl<T, U> From<Vector2D<T>> for (U, U)
386where
387    U: From<T> + Copy + Clone,
388{
389    fn from(src: Vector2D<T>) -> (U, U) {
390        (U::from(src.x), U::from(src.y))
391    }
392}
393
394impl<T, U> From<(U, U)> for Vector2D<T>
395where
396    T: From<U>,
397    U: Copy + Clone,
398{
399    fn from(src: (U, U)) -> Vector2D<T> {
400        Vector2D {
401            x: src.0.into(),
402            y: src.1.into(),
403        }
404    }
405}
406
407impl<T, U> From<[U; 2]> for Vector2D<T>
408where
409    T: From<U>,
410    U: Copy + Clone,
411{
412    fn from(src: [U; 2]) -> Vector2D<T> {
413        Vector2D {
414            x: src[0].into(),
415            y: src[1].into(),
416        }
417    }
418}
419
420impl<T> Index<usize> for Vector2D<T> {
421    type Output = T;
422
423    /// Only possible for `idx` in {0, 1} - panics otherwise
424    fn index(&self, idx: usize) -> &Self::Output {
425        match idx {
426            0 => &self.x,
427            1 => &self.y,
428            _ => panic!("Index '{}' was out of range for Vector2D", idx),
429        }
430    }
431}
432
433impl<T> IndexMut<usize> for Vector2D<T> {
434    /// Only possible for `idx` in {0, 1} - panics otherwise
435    fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
436        match idx {
437            0 => &mut self.x,
438            1 => &mut self.y,
439            _ => panic!("Index '{}' was out of range for Vector2D", idx),
440        }
441    }
442}
443
444// Specific Primitive Implementations
445
446impl Vector2D<f32> {
447    /// Get the length of the vector. If possible, favour `length_squared()` over
448    /// this function, as it is more performant.
449    pub fn length(self) -> f32 {
450        f32::sqrt(self.length_squared())
451    }
452
453    /// Get a new vector with the same direction as this vector, but with a length
454    /// of 1.0. If the the length of the vector is 0, then the original vector is
455    /// returned.
456    pub fn normalise(self) -> Self {
457        let len = self.length();
458        if len == 0.0 {
459            self
460        } else {
461            self / len
462        }
463    }
464
465    /// Get the vector's direction in radians.
466    pub fn angle(self) -> f32 {
467        self.y.atan2(self.x)
468    }
469
470    fn_simple_as!(as_i32s, i32);
471    fn_simple_as!(as_i64s, i64);
472    fn_simple_as!(as_isizes, isize);
473    fn_lower_bounded_as!(as_u32s, u32, 0.0);
474    fn_lower_bounded_as!(as_u64s, u64, 0.0);
475    fn_lower_bounded_as!(as_usizes, usize, 0.0);
476}
477
478impl Vector2D<f64> {
479    /// Get the length of the vector. If possible, favour `length_squared()` over
480    /// this function, as it is more performant.
481    pub fn length(self) -> f64 {
482        f64::sqrt(self.length_squared())
483    }
484
485    /// Get a new vector with the same direction as this vector, but with a length
486    /// of 1.0. If the the length of the vector is 0, then the original vector is
487    /// returned.
488    pub fn normalise(self) -> Self {
489        let len = self.length();
490        if len == 0.0 {
491            self
492        } else {
493            self / len
494        }
495    }
496
497    /// Get the vector's direction in radians.
498    pub fn angle(self) -> f64 {
499        self.y.atan2(self.x)
500    }
501
502    fn_simple_as!(as_i32s, i32);
503    fn_simple_as!(as_i64s, i64);
504    fn_simple_as!(as_isize, isize);
505    fn_simple_as!(as_f32, f32);
506    fn_lower_bounded_as!(as_u32s, u32, 0.0);
507    fn_lower_bounded_as!(as_u64s, u64, 0.0);
508    fn_lower_bounded_as!(as_usizes, usize, 0.0);
509}
510
511impl Vector2D<i32> {
512    fn_simple_as!(as_isizes, isize);
513    fn_simple_as!(as_f32s, f32);
514    fn_simple_as!(as_f64s, f64);
515    fn_lower_bounded_as!(as_u32s, u32, 0);
516    fn_lower_bounded_as!(as_u64s, u64, 0);
517    fn_lower_bounded_as!(as_usizes, usize, 0);
518}
519
520impl Vector2D<i64> {
521    fn_bounded_as!(as_i32s, i32, i32::MIN.into(), i32::MAX.into());
522    fn_simple_as!(as_i64s, isize);
523    fn_simple_as!(as_f32s, f32);
524    fn_simple_as!(as_f64s, f64);
525    fn_lower_bounded_as!(as_u32s, u32, 0);
526    fn_lower_bounded_as!(as_u64s, u64, 0);
527    fn_lower_bounded_as!(as_usizes, usize, 0);
528}
529
530impl Vector2D<isize> {
531    fn_simple_as!(as_i32s, i32);
532    fn_simple_as!(as_i64s, i64);
533    fn_simple_as!(as_f32s, f32);
534    fn_simple_as!(as_f64s, f64);
535    fn_lower_bounded_as!(as_u32s, u32, 0);
536    fn_lower_bounded_as!(as_u64s, u64, 0);
537    fn_lower_bounded_as!(as_usizes, usize, 0);
538}
539
540impl Vector2D<u32> {
541    fn_bounded_as!(as_i32s, i32, 0, i32::MAX as u32);
542    fn_simple_as!(as_i64s, i64);
543    fn_simple_as!(as_isizes, isize);
544    fn_simple_as!(as_f32s, f32);
545    fn_simple_as!(as_f64s, f64);
546    fn_simple_as!(as_usizes, usize);
547}
548
549impl Vector2D<u64> {
550    fn_bounded_as!(as_i32s, i32, 0, i32::MAX as u64);
551    fn_bounded_as!(as_i64s, i64, 0, i64::MAX as u64);
552    fn_simple_as!(as_isizes, isize);
553    fn_simple_as!(as_f32s, f32);
554    fn_simple_as!(as_f64s, f64);
555    fn_simple_as!(as_u32s, u32);
556    fn_simple_as!(as_usizes, usize);
557}
558
559impl Vector2D<usize> {
560    fn_simple_as!(as_i32s, i32);
561    fn_simple_as!(as_i64s, i64);
562    fn_bounded_as!(as_isizes, isize, 0, isize::MAX as usize);
563    fn_simple_as!(as_f32s, f32);
564    fn_simple_as!(as_f64s, f64);
565    fn_simple_as!(as_u32s, u32);
566    fn_simple_as!(as_u64s, u64);
567}
568
569///  Blanket impls for `min_each`, `max_each`, and `clamp_each`
570impl<T> Vector2D<T>
571where
572    T: PartialOrd + Copy + Clone,
573{
574    // PartialOrd types don't get max, min, or clamp functions so we write our own. When comparison
575    // is impossible, we just return the first arg, as v1 this is the pre-existing value inside our
576    // vector and keeping it intact in such cases is somewhat reasonable enough.
577
578    fn min_t(v1: T, v2: T) -> T {
579        match v1.partial_cmp(&v2) {
580            None => v1,
581            Some(Ordering::Less) => v1,
582            Some(_) => v2,
583        }
584    }
585
586    fn max_t(v1: T, v2: T) -> T {
587        match v1.partial_cmp(&v2) {
588            None => v1,
589            Some(Ordering::Greater) => v1,
590            Some(_) => v2,
591        }
592    }
593
594    fn clamp_t(v: T, min: T, max: T) -> T {
595        Self::max_t(Self::min_t(v, max), min)
596    }
597
598    /// Compares each component against the provided value, and returns a new vector with the lower
599    /// value in each component
600    pub fn min_each(self, value: T) -> Self {
601        Self {
602            x: Self::min_t(self.x, value),
603            y: Self::min_t(self.y, value),
604        }
605    }
606
607    /// Compares each component against the provided value, and returns a new vector with the higher
608    /// value in each component
609    pub fn max_each(self, value: T) -> Self {
610        Self {
611            x: Self::max_t(self.x, value),
612            y: Self::max_t(self.y, value),
613        }
614    }
615
616    /// Returns a new vector where each component has the values of the source vector clamped within
617    /// the provided bounds
618    pub fn clamp_each(self, min: T, max: T) -> Self {
619        Self {
620            x: Self::clamp_t(self.x, min, max),
621            y: Self::clamp_t(self.y, min, max),
622        }
623    }
624}
625
626// Ops Implementations
627
628impl<T, O> Add<Vector2D<T>> for Vector2D<T>
629where
630    T: Add<T, Output = O> + Copy + Clone,
631{
632    type Output = Vector2D<O>;
633    fn add(self, rhs: Vector2D<T>) -> Self::Output {
634        Vector2D {
635            x: self.x + rhs.x,
636            y: self.y + rhs.y,
637        }
638    }
639}
640
641impl<T, O> Add<&Vector2D<T>> for &Vector2D<T>
642where
643    T: Add<T, Output = O> + Copy + Clone,
644{
645    type Output = Vector2D<O>;
646    fn add(self, rhs: &Vector2D<T>) -> Self::Output {
647        Vector2D {
648            x: self.x + rhs.x,
649            y: self.y + rhs.y,
650        }
651    }
652}
653
654impl<T> AddAssign<Vector2D<T>> for Vector2D<T>
655where
656    T: Add<T, Output = T> + Copy + Clone,
657{
658    fn add_assign(&mut self, rhs: Vector2D<T>) {
659        self.x = self.x + rhs.x;
660        self.y = self.y + rhs.y;
661    }
662}
663
664impl<T, O> Sub<Vector2D<T>> for Vector2D<T>
665where
666    T: Sub<T, Output = O> + Copy + Clone,
667{
668    type Output = Vector2D<O>;
669    fn sub(self, rhs: Vector2D<T>) -> Self::Output {
670        Vector2D {
671            x: self.x - rhs.x,
672            y: self.y - rhs.y,
673        }
674    }
675}
676
677impl<T, O> Sub<&Vector2D<T>> for &Vector2D<T>
678where
679    T: Sub<T, Output = O> + Copy + Clone,
680{
681    type Output = Vector2D<O>;
682    fn sub(self, rhs: &Vector2D<T>) -> Self::Output {
683        Vector2D {
684            x: self.x - rhs.x,
685            y: self.y - rhs.y,
686        }
687    }
688}
689
690impl<T> SubAssign<Vector2D<T>> for Vector2D<T>
691where
692    T: Sub<T, Output = T> + Copy + Clone,
693{
694    fn sub_assign(&mut self, rhs: Vector2D<T>) {
695        self.x = self.x - rhs.x;
696        self.y = self.y - rhs.y;
697    }
698}
699
700impl<T, O> Mul<T> for Vector2D<T>
701where
702    T: Mul<T, Output = O> + Copy + Clone,
703{
704    type Output = Vector2D<O>;
705    fn mul(self, rhs: T) -> Self::Output {
706        Vector2D {
707            x: self.x * rhs,
708            y: self.y * rhs,
709        }
710    }
711}
712
713impl<T, O> Mul<T> for &Vector2D<T>
714where
715    T: Mul<T, Output = O> + Copy + Clone,
716{
717    type Output = Vector2D<O>;
718    fn mul(self, rhs: T) -> Self::Output {
719        Self::Output {
720            x: self.x * rhs,
721            y: self.y * rhs,
722        }
723    }
724}
725
726impl<T> MulAssign<T> for Vector2D<T>
727where
728    T: Mul<T, Output = T> + Copy + Clone,
729{
730    fn mul_assign(&mut self, rhs: T) {
731        self.x = self.x * rhs;
732        self.y = self.y * rhs;
733    }
734}
735
736impl<T, O> Div<T> for Vector2D<T>
737where
738    T: Div<T, Output = O> + Copy + Clone,
739{
740    type Output = Vector2D<O>;
741    fn div(self, rhs: T) -> Self::Output {
742        Self::Output {
743            x: self.x / rhs,
744            y: self.y / rhs,
745        }
746    }
747}
748
749impl<T, O> Div<T> for &Vector2D<T>
750where
751    T: Div<T, Output = O> + Copy + Clone,
752{
753    type Output = Vector2D<O>;
754    fn div(self, rhs: T) -> Self::Output {
755        Self::Output {
756            x: self.x / rhs,
757            y: self.y / rhs,
758        }
759    }
760}
761
762impl<T> DivAssign<T> for Vector2D<T>
763where
764    T: Div<T, Output = T> + Copy + Clone,
765{
766    fn div_assign(&mut self, rhs: T) {
767        self.x = self.x / rhs;
768        self.y = self.y / rhs;
769    }
770}