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