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}