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}