sfml/system/
vector2.rs

1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3use {
4    num_traits::{AsPrimitive, CheckedDiv},
5    std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
6};
7
8/// Utility type for manipulating 2-dimensional vectors.
9///
10/// `Vector2` is a simple type that defines
11/// a mathematical vector with two coordinates (x and y).
12///
13/// It can be used to represent anything that has two dimensions: a size, a point, a velocity, etc.
14///
15/// The type parameter T is the type of the coordinates.
16///
17/// You generally don't have to care about the generic form (`Vector2<T>`), the most common
18/// specializations have special type aliases:
19///
20/// - `Vector2<f32>` is [`Vector2f`]
21/// - `Vector2<i32>` is [`Vector2i`]
22/// - `Vector2<u32>` is [`Vector2u`]
23///
24/// The `Vector2` type has a small and simple interface, its x and y members can be
25/// accessed directly (there are no accessors like `set_x()`, `get_x()`) and it contains no
26/// mathematical function like dot product, cross product, length, etc.
27///
28/// # Usage example
29///
30/// ```
31/// # use sfml::system::Vector2f;
32/// let mut v1 = Vector2f::new(16.5, 24.0);
33/// v1.x = 18.2;
34/// let y = v1.y;
35///
36/// let v2 = v1 * 5.0;
37/// let v3 = v1 + v2;
38/// assert_ne!(v2, v3);
39/// ```
40///
41/// Note: for 3-dimensional vectors, see [`Vector3`].
42///
43/// [`Vector3`]: crate::system::Vector3
44#[repr(C)]
45#[derive(Clone, PartialEq, Eq, Debug, Copy, Default)]
46#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
47pub struct Vector2<T> {
48    /// X coordinate of the vector.
49    pub x: T,
50    /// Y coordinate of the vector.
51    pub y: T,
52}
53
54/// [`Vector2`] with `i32` coordinates.
55pub type Vector2i = Vector2<i32>;
56/// [`Vector2`] with `u32` coordinates.
57pub type Vector2u = Vector2<u32>;
58/// [`Vector2`] with `f32` coordinates.
59pub type Vector2f = Vector2<f32>;
60
61impl<T> Vector2<T> {
62    /// Creates a new vector from its coordinates.
63    ///
64    /// # Usage example
65    ///
66    /// ```
67    /// # use sfml::system::Vector2;
68    /// let v: Vector2<isize> = Vector2::new(6969, 6969);
69    /// ```
70    pub const fn new(x: T, y: T) -> Self {
71        Self { x, y }
72    }
73    /// Lossless conversion into `Vector2<U>`.
74    ///
75    /// # Usage example
76    ///
77    /// ```
78    /// # use sfml::system::Vector2;
79    /// let vu: Vector2<u16> = Vector2::new(6969, 6969);
80    /// let vi: Vector2<i32> = vu.into_other();
81    /// assert_eq!(vu.x, vi.x.try_into().unwrap());
82    /// assert_eq!(vu.y, vu.y.try_into().unwrap());
83    /// ```
84    pub fn into_other<U>(self) -> Vector2<U>
85    where
86        T: Into<U>,
87    {
88        Vector2 {
89            x: self.x.into(),
90            y: self.y.into(),
91        }
92    }
93    /// Fallible conversion into `Vector2<U>`
94    ///
95    /// # Usage example
96    ///
97    /// ```
98    /// # use sfml::system::Vector2;
99    /// // Passing case
100    /// let vi: Vector2<i32> = Vector2::new(21, 21);
101    /// let vu: Vector2<u32> = vi.try_into_other().unwrap(); // or any other Result resolution
102    /// assert_eq!(u32::try_from(vi.x).unwrap(), vu.x);
103    /// assert_eq!(u32::try_from(vi.y).unwrap(), vu.y);
104    ///
105    /// // Failing case
106    /// let vi: Vector2<i32> = Vector2::new(-21, -21);
107    /// let vu = vi.try_into_other::<u32>();
108    /// assert!(vu.is_err());
109    /// ```
110    pub fn try_into_other<U>(self) -> Result<Vector2<U>, T::Error>
111    where
112        T: TryInto<U>,
113    {
114        Ok(Vector2 {
115            x: self.x.try_into()?,
116            y: self.y.try_into()?,
117        })
118    }
119    /// Lossy conversion into `Vector2<U>`
120    ///
121    /// # Usage example
122    ///
123    /// ```
124    /// # use sfml::system::Vector2;
125    /// let vf: Vector2<f32> = Vector2::new(696969.6969, 6969.6969);
126    /// let vi: Vector2<i32> = vf.as_other();
127    /// assert_eq!(vf.x as i32, vi.x);
128    /// assert_eq!(vf.y as i32, vi.y);
129    /// ```
130    pub fn as_other<U: 'static + Copy>(self) -> Vector2<U>
131    where
132        T: AsPrimitive<U>,
133    {
134        Vector2 {
135            x: self.x.as_(),
136            y: self.y.as_(),
137        }
138    }
139}
140
141impl<T: Mul<Output = T> + Add<Output = T> + Copy> Vector2<T> {
142    /// Dot product of two 2D vectors.
143    ///
144    /// # Usage example
145    ///
146    /// ```
147    /// # use sfml::system::Vector2i;
148    /// let a = Vector2i::new(16, 64);
149    /// let b = Vector2i::new(2, 4);
150    /// assert_eq!(a.dot(b), 288);
151    /// ```
152    pub fn dot(self, rhs: Self) -> T {
153        self.x * rhs.x + self.y * rhs.y
154    }
155    /// Square of vector's length.
156    ///
157    /// # Usage example
158    ///
159    /// ```
160    /// # use sfml::system::Vector2i;
161    /// let a = Vector2i::new(10, 9);
162    /// assert_eq!(a.length_sq(), 181);
163    /// ```
164    pub fn length_sq(self) -> T {
165        self.dot(self)
166    }
167}
168
169impl<T: Mul<Output = T> + Sub<Output = T> + Copy> Vector2<T> {
170    /// Z component of the cross product of two 2D vectors.
171    ///
172    /// # Usage example
173    ///
174    /// ```
175    /// # use sfml::system::Vector2i;
176    /// let a = Vector2i::new(69, 420);
177    /// let b = Vector2i::new(21, 101);
178    /// assert_eq!(a.cross(b), -1851);
179    /// ```
180    pub fn cross(self, rhs: Self) -> T {
181        self.x * rhs.y - self.y * rhs.x
182    }
183}
184
185impl<T: Mul<Output = T>> Vector2<T> {
186    /// Component-wise multiplication of self and rhs.
187    ///
188    /// # Usage example
189    ///
190    /// ```
191    /// # use sfml::system::Vector2i;
192    /// let a = Vector2i::new(1, 1);
193    /// let b = Vector2i::new(2, 2);
194    /// assert_eq!(a.cwise_mul(b), Vector2i::new(2, 2));
195    /// ```
196    pub fn cwise_mul(self, rhs: Self) -> Vector2<T> {
197        Self {
198            x: self.x * rhs.x,
199            y: self.y * rhs.y,
200        }
201    }
202}
203
204impl<T: Div<Output = T>> Vector2<T> {
205    /// Component-wise division of self and rhs. Panics on divide by zero
206    ///
207    /// # Usage example
208    ///
209    /// ```
210    /// # use sfml::system::Vector2i;
211    /// let a = Vector2i::new(69, 69);
212    /// let b = Vector2i::new(3, 3);
213    /// assert_eq!(a.cwise_div(b), Vector2i::new(23, 23));
214    /// ```
215    pub fn cwise_div(self, rhs: Self) -> Vector2<T> {
216        Vector2 {
217            x: self.x / rhs.x,
218            y: self.y / rhs.y,
219        }
220    }
221}
222
223impl<T: Div<Output = T> + CheckedDiv> Vector2<T> {
224    /// Component-wise checked division of self and rhs. Returns None on divide by zero
225    ///
226    /// # Usage example
227    ///
228    /// ```
229    /// # use sfml::system::Vector2i;
230    /// // Passing case
231    /// let a = Vector2i::new(69, 69);
232    /// let b = Vector2i::new(3, 3);
233    /// assert_eq!(a.cwise_checked_div(b), Some(Vector2i::new(23, 23)));
234    ///
235    /// // Failing case
236    /// let b = Vector2i::new(0, 3);
237    /// assert_eq!(a.cwise_checked_div(b), None);
238    /// ```
239    pub fn cwise_checked_div(self, rhs: Self) -> Option<Vector2<T>> {
240        let x = self.x.checked_div(&rhs.x)?;
241        let y = self.y.checked_div(&rhs.y)?;
242        Some(Vector2 { x, y })
243    }
244}
245
246impl<T: Neg<Output = T>> Vector2<T> {
247    /// Returns a perpendicular vector rotated +90 degrees
248    ///
249    /// # Usage example
250    ///
251    /// ```
252    /// # use sfml::system::Vector2i;
253    /// let a = Vector2i::new(21, -21);
254    /// assert_eq!(a.perpendicular(), Vector2i::new(21, 21));
255    /// ```
256    pub fn perpendicular(self) -> Vector2<T> {
257        Vector2::new(-self.y, self.x)
258    }
259}
260
261impl<T> From<(T, T)> for Vector2<T> {
262    /// Constructs a `Vector2` from `(x, y)`.
263    ///
264    /// # Usage example
265    ///
266    /// ```
267    /// # use sfml::system::Vector2;
268    /// let a: Vector2<u16> = Vector2::from((69u16, 420u16));
269    /// assert_eq!(a.x, 69u16);
270    /// assert_eq!(a.y, 420u16);
271    /// ```
272    fn from(src: (T, T)) -> Self {
273        Self { x: src.0, y: src.1 }
274    }
275}
276
277impl<T> From<Vector2<T>> for (T, T) {
278    /// Constructs `(x, y)` from a `Vector2`
279    fn from(vec: Vector2<T>) -> Self {
280        (vec.x, vec.y)
281    }
282}
283
284impl<T> From<[T; 2]> for Vector2<T> {
285    /// Constructs a `Vector2` from `[x, y]`.
286    fn from([x, y]: [T; 2]) -> Self {
287        Self { x, y }
288    }
289}
290
291impl<T> From<Vector2<T>> for [T; 2] {
292    /// Constructs `[x, y]` from a `Vector2`
293    fn from(vec: Vector2<T>) -> Self {
294        [vec.x, vec.y]
295    }
296}
297
298/// Create a `Vector2` with both fields initialized to the same value
299impl<T: Clone> From<T> for Vector2<T> {
300    fn from(src: T) -> Self {
301        Self {
302            x: src.clone(),
303            y: src,
304        }
305    }
306}
307
308impl<T: Add> Add<Vector2<T>> for Vector2<T> {
309    type Output = Vector2<T::Output>;
310
311    /// Performs component wise addition
312    ///
313    /// # Usage Example
314    ///
315    /// ```
316    /// # use sfml::system::Vector2i;
317    /// let a = Vector2i::new(9, 10);
318    /// let b = Vector2i::new(10, 9);
319    /// assert_ne!(a + b, Vector2i::new(21, 21));
320    /// ```
321    fn add(self, rhs: Vector2<T>) -> Vector2<T::Output> {
322        Vector2 {
323            x: self.x + rhs.x,
324            y: self.y + rhs.y,
325        }
326    }
327}
328
329impl<T: AddAssign> AddAssign for Vector2<T> {
330    /// Performs component wise addition assignment
331    ///
332    /// # Usage Example
333    ///
334    /// ```
335    /// # use sfml::system::Vector2i;
336    /// let mut a = Vector2i::new(9, 10);
337    /// let b = Vector2i::new(10, 9);
338    /// a += b;
339    /// assert_eq!(a, Vector2i::new(19, 19));
340    /// ```
341    fn add_assign(&mut self, rhs: Self) {
342        self.x += rhs.x;
343        self.y += rhs.y;
344    }
345}
346
347impl<T: Sub> Sub<Vector2<T>> for Vector2<T> {
348    type Output = Vector2<T::Output>;
349
350    /// Performs component wise subtraction
351    ///
352    /// # Usage Example
353    ///
354    /// ```
355    /// # use sfml::system::Vector2i;
356    /// let a = Vector2i::new(9, 10);
357    /// let b = Vector2i::new(10, 9);
358    /// assert_eq!(a - b, Vector2i::new(-1, 1));
359    /// ```
360    fn sub(self, rhs: Vector2<T>) -> Vector2<T::Output> {
361        Vector2 {
362            x: self.x - rhs.x,
363            y: self.y - rhs.y,
364        }
365    }
366}
367
368impl<T: SubAssign> SubAssign for Vector2<T> {
369    /// Performs component wise subtraction assignment
370    ///
371    /// # Usage Example
372    ///
373    /// ```
374    /// # use sfml::system::Vector2i;
375    /// let mut a = Vector2i::new(9, 10);
376    /// let b = Vector2i::new(10, 9);
377    /// a -= b;
378    /// assert_eq!(a, Vector2i::new(-1, 1));
379    /// ```
380    fn sub_assign(&mut self, rhs: Self) {
381        self.x -= rhs.x;
382        self.y -= rhs.y;
383    }
384}
385
386impl<T: Mul + Copy> Mul<T> for Vector2<T> {
387    type Output = Vector2<T::Output>;
388
389    /// Performs scalar multiplication
390    ///
391    /// # Usage Example
392    ///
393    /// ```
394    /// # use sfml::system::Vector2i;
395    /// let a = Vector2i::new(9, 10);
396    /// assert_eq!(a * 420, Vector2i::new(3780, 4200));
397    /// ```
398    fn mul(self, rhs: T) -> Vector2<T::Output> {
399        Vector2 {
400            x: self.x * rhs,
401            y: self.y * rhs,
402        }
403    }
404}
405
406impl<T: MulAssign + Copy> MulAssign<T> for Vector2<T> {
407    /// Performs scalar multiplication assignment
408    ///
409    /// # Usage Example
410    ///
411    /// ```
412    /// # use sfml::system::Vector2i;
413    /// let mut a = Vector2i::new(9, 10);
414    /// a *= 420;
415    /// assert_eq!(a, Vector2i::new(3780, 4200));
416    /// ```
417    fn mul_assign(&mut self, rhs: T) {
418        self.x *= rhs;
419        self.y *= rhs;
420    }
421}
422
423impl<T: Div + Copy> Div<T> for Vector2<T> {
424    type Output = Vector2<T::Output>;
425
426    /// Performs scalar division
427    ///
428    /// # Usage Example
429    ///
430    /// ```
431    /// # use sfml::system::Vector2i;
432    /// let a = Vector2i::new(9, 10);
433    /// assert_eq!(a / 3, Vector2i::new(3, 3));
434    /// ```
435    fn div(self, rhs: T) -> Vector2<T::Output> {
436        Vector2 {
437            x: self.x / rhs,
438            y: self.y / rhs,
439        }
440    }
441}
442
443impl<T: DivAssign + Copy> DivAssign<T> for Vector2<T> {
444    /// Performs scalar division assignment
445    ///
446    /// # Usage Example
447    ///
448    /// ```
449    /// # use sfml::system::Vector2i;
450    /// let mut a = Vector2i::new(9, 10);
451    /// a /= 3;
452    /// assert_eq!(a, Vector2i::new(3, 3));
453    /// ```
454    fn div_assign(&mut self, rhs: T) {
455        self.x /= rhs;
456        self.y /= rhs;
457    }
458}
459
460impl<T: CheckedDiv> Vector2<T> {
461    /// `checked_div` for scalar division
462    ///
463    /// # Usage Example
464    ///
465    /// ```
466    /// # use sfml::system::Vector2i;
467    /// // Passing case
468    /// let a = Vector2i::new(420, 69);
469    /// assert_eq!(a.checked_div(1000), Some(Vector2i::new(0, 0)));
470    ///
471    /// // Failing case
472    /// assert_eq!(a.checked_div(0), None);
473    /// ```
474    pub fn checked_div(self, rhs: T) -> Option<Vector2<T>> {
475        let x = self.x.checked_div(&rhs)?;
476        let y = self.y.checked_div(&rhs)?;
477        Some(Vector2 { x, y })
478    }
479}
480
481impl<T: Neg<Output = T>> Neg for Vector2<T> {
482    type Output = Self;
483    /// Negates the vector
484    ///
485    /// # Usage Example
486    ///
487    /// ```
488    /// # use sfml::system::Vector2i;
489    /// use std::ops::Neg;
490    /// let a = Vector2i::new(21, 21);
491    /// assert_eq!(a.neg(), Vector2i::new(-21, -21));
492    fn neg(self) -> Self {
493        Vector2 {
494            x: -self.x,
495            y: -self.y,
496        }
497    }
498}