1// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution.
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
10use super::UnknownUnit;
11use crate::approxeq::ApproxEq;
12use crate::approxord::{max, min};
13use crate::length::Length;
14use crate::num::*;
15use crate::point::{point2, point3, Point2D, Point3D};
16use crate::scale::Scale;
17use crate::size::{size2, size3, Size2D, Size3D};
18use crate::transform2d::Transform2D;
19use crate::transform3d::Transform3D;
20use crate::trig::Trig;
21use crate::Angle;
22use core::cmp::{Eq, PartialEq};
23use core::fmt;
24use core::hash::Hash;
25use core::iter::Sum;
26use core::marker::PhantomData;
27use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
28#[cfg(feature = "mint")]
29use mint;
30use num_traits::real::Real;
31use num_traits::{Float, NumCast, Signed};
32#[cfg(feature = "serde")]
33use serde;
34
35#[cfg(feature = "bytemuck")]
36use bytemuck::{Zeroable, Pod};
37
38/// A 2d Vector tagged with a unit.
39#[repr(C)]
40pub struct Vector2D<T, U> {
41 /// The `x` (traditionally, horizontal) coordinate.
42 pub x: T,
43 /// The `y` (traditionally, vertical) coordinate.
44 pub y: T,
45 #[doc(hidden)]
46 pub _unit: PhantomData<U>,
47}
48
49mint_vec!(Vector2D[x, y] = Vector2);
50
51impl<T: Copy, U> Copy for Vector2D<T, U> {}
52
53impl<T: Clone, U> Clone for Vector2D<T, U> {
54 fn clone(&self) -> Self {
55 Vector2D {
56 x: self.x.clone(),
57 y: self.y.clone(),
58 _unit: PhantomData,
59 }
60 }
61}
62
63#[cfg(feature = "serde")]
64impl<'de, T, U> serde::Deserialize<'de> for Vector2D<T, U>
65where
66 T: serde::Deserialize<'de>,
67{
68 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
69 where
70 D: serde::Deserializer<'de>,
71 {
72 let (x, y) = serde::Deserialize::deserialize(deserializer)?;
73 Ok(Vector2D {
74 x,
75 y,
76 _unit: PhantomData,
77 })
78 }
79}
80
81#[cfg(feature = "serde")]
82impl<T, U> serde::Serialize for Vector2D<T, U>
83where
84 T: serde::Serialize,
85{
86 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
87 where
88 S: serde::Serializer,
89 {
90 (&self.x, &self.y).serialize(serializer)
91 }
92}
93
94#[cfg(feature = "arbitrary")]
95impl<'a, T, U> arbitrary::Arbitrary<'a> for Vector2D<T, U>
96where
97 T: arbitrary::Arbitrary<'a>,
98{
99 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self>
100 {
101 let (x, y) = arbitrary::Arbitrary::arbitrary(u)?;
102 Ok(Vector2D {
103 x,
104 y,
105 _unit: PhantomData,
106 })
107 }
108}
109
110#[cfg(feature = "bytemuck")]
111unsafe impl<T: Zeroable, U> Zeroable for Vector2D<T, U> {}
112
113#[cfg(feature = "bytemuck")]
114unsafe impl<T: Pod, U: 'static> Pod for Vector2D<T, U> {}
115
116impl<T: Eq, U> Eq for Vector2D<T, U> {}
117
118impl<T: PartialEq, U> PartialEq for Vector2D<T, U> {
119 fn eq(&self, other: &Self) -> bool {
120 self.x == other.x && self.y == other.y
121 }
122}
123
124impl<T: Hash, U> Hash for Vector2D<T, U> {
125 fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
126 self.x.hash(state:h);
127 self.y.hash(state:h);
128 }
129}
130
131impl<T: Zero, U> Zero for Vector2D<T, U> {
132 /// Constructor, setting all components to zero.
133 #[inline]
134 fn zero() -> Self {
135 Vector2D::new(x:Zero::zero(), y:Zero::zero())
136 }
137}
138
139impl<T: fmt::Debug, U> fmt::Debug for Vector2D<T, U> {
140 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
141 f.debug_tuple(name:"").field(&self.x).field(&self.y).finish()
142 }
143}
144
145impl<T: Default, U> Default for Vector2D<T, U> {
146 fn default() -> Self {
147 Vector2D::new(x:Default::default(), y:Default::default())
148 }
149}
150
151impl<T, U> Vector2D<T, U> {
152 /// Constructor, setting all components to zero.
153 #[inline]
154 pub fn zero() -> Self
155 where
156 T: Zero,
157 {
158 Vector2D::new(Zero::zero(), Zero::zero())
159 }
160
161 /// Constructor, setting all components to one.
162 #[inline]
163 pub fn one() -> Self
164 where
165 T: One,
166 {
167 Vector2D::new(One::one(), One::one())
168 }
169
170 /// Constructor taking scalar values directly.
171 #[inline]
172 pub const fn new(x: T, y: T) -> Self {
173 Vector2D {
174 x,
175 y,
176 _unit: PhantomData,
177 }
178 }
179
180 /// Constructor setting all components to the same value.
181 #[inline]
182 pub fn splat(v: T) -> Self
183 where
184 T: Clone,
185 {
186 Vector2D {
187 x: v.clone(),
188 y: v,
189 _unit: PhantomData,
190 }
191 }
192
193 /// Constructor taking angle and length
194 pub fn from_angle_and_length(angle: Angle<T>, length: T) -> Self
195 where
196 T: Trig + Mul<Output = T> + Copy,
197 {
198 vec2(length * angle.radians.cos(), length * angle.radians.sin())
199 }
200
201 /// Constructor taking properly Lengths instead of scalar values.
202 #[inline]
203 pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self {
204 vec2(x.0, y.0)
205 }
206
207 /// Tag a unit-less value with units.
208 #[inline]
209 pub fn from_untyped(p: Vector2D<T, UnknownUnit>) -> Self {
210 vec2(p.x, p.y)
211 }
212
213 /// Computes the vector with absolute values of each component.
214 ///
215 /// # Example
216 ///
217 /// ```rust
218 /// # use std::{i32, f32};
219 /// # use euclid::vec2;
220 /// enum U {}
221 ///
222 /// assert_eq!(vec2::<_, U>(-1, 2).abs(), vec2(1, 2));
223 ///
224 /// let vec = vec2::<_, U>(f32::NAN, -f32::MAX).abs();
225 /// assert!(vec.x.is_nan());
226 /// assert_eq!(vec.y, f32::MAX);
227 /// ```
228 ///
229 /// # Panics
230 ///
231 /// The behavior for each component follows the scalar type's implementation of
232 /// `num_traits::Signed::abs`.
233 pub fn abs(self) -> Self
234 where
235 T: Signed,
236 {
237 vec2(self.x.abs(), self.y.abs())
238 }
239
240 /// Dot product.
241 #[inline]
242 pub fn dot(self, other: Self) -> T
243 where
244 T: Add<Output = T> + Mul<Output = T>,
245 {
246 self.x * other.x + self.y * other.y
247 }
248
249 /// Returns the norm of the cross product [self.x, self.y, 0] x [other.x, other.y, 0].
250 #[inline]
251 pub fn cross(self, other: Self) -> T
252 where
253 T: Sub<Output = T> + Mul<Output = T>,
254 {
255 self.x * other.y - self.y * other.x
256 }
257
258 /// Returns the component-wise multiplication of the two vectors.
259 #[inline]
260 pub fn component_mul(self, other: Self) -> Self
261 where
262 T: Mul<Output = T>,
263 {
264 vec2(self.x * other.x, self.y * other.y)
265 }
266
267 /// Returns the component-wise division of the two vectors.
268 #[inline]
269 pub fn component_div(self, other: Self) -> Self
270 where
271 T: Div<Output = T>,
272 {
273 vec2(self.x / other.x, self.y / other.y)
274 }
275}
276
277impl<T: Copy, U> Vector2D<T, U> {
278 /// Create a 3d vector from this one, using the specified z value.
279 #[inline]
280 pub fn extend(self, z: T) -> Vector3D<T, U> {
281 vec3(self.x, self.y, z)
282 }
283
284 /// Cast this vector into a point.
285 ///
286 /// Equivalent to adding this vector to the origin.
287 #[inline]
288 pub fn to_point(self) -> Point2D<T, U> {
289 Point2D {
290 x: self.x,
291 y: self.y,
292 _unit: PhantomData,
293 }
294 }
295
296 /// Swap x and y.
297 #[inline]
298 pub fn yx(self) -> Self {
299 vec2(self.y, self.x)
300 }
301
302 /// Cast this vector into a size.
303 #[inline]
304 pub fn to_size(self) -> Size2D<T, U> {
305 size2(self.x, self.y)
306 }
307
308 /// Drop the units, preserving only the numeric value.
309 #[inline]
310 pub fn to_untyped(self) -> Vector2D<T, UnknownUnit> {
311 vec2(self.x, self.y)
312 }
313
314 /// Cast the unit.
315 #[inline]
316 pub fn cast_unit<V>(self) -> Vector2D<T, V> {
317 vec2(self.x, self.y)
318 }
319
320 /// Cast into an array with x and y.
321 #[inline]
322 pub fn to_array(self) -> [T; 2] {
323 [self.x, self.y]
324 }
325
326 /// Cast into a tuple with x and y.
327 #[inline]
328 pub fn to_tuple(self) -> (T, T) {
329 (self.x, self.y)
330 }
331
332 /// Convert into a 3d vector with `z` coordinate equals to `T::zero()`.
333 #[inline]
334 pub fn to_3d(self) -> Vector3D<T, U>
335 where
336 T: Zero,
337 {
338 vec3(self.x, self.y, Zero::zero())
339 }
340
341 /// Rounds each component to the nearest integer value.
342 ///
343 /// This behavior is preserved for negative values (unlike the basic cast).
344 ///
345 /// ```rust
346 /// # use euclid::vec2;
347 /// enum Mm {}
348 ///
349 /// assert_eq!(vec2::<_, Mm>(-0.1, -0.8).round(), vec2::<_, Mm>(0.0, -1.0))
350 /// ```
351 #[inline]
352 #[must_use]
353 pub fn round(self) -> Self
354 where
355 T: Round,
356 {
357 vec2(self.x.round(), self.y.round())
358 }
359
360 /// Rounds each component to the smallest integer equal or greater than the original value.
361 ///
362 /// This behavior is preserved for negative values (unlike the basic cast).
363 ///
364 /// ```rust
365 /// # use euclid::vec2;
366 /// enum Mm {}
367 ///
368 /// assert_eq!(vec2::<_, Mm>(-0.1, -0.8).ceil(), vec2::<_, Mm>(0.0, 0.0))
369 /// ```
370 #[inline]
371 #[must_use]
372 pub fn ceil(self) -> Self
373 where
374 T: Ceil,
375 {
376 vec2(self.x.ceil(), self.y.ceil())
377 }
378
379 /// Rounds each component to the biggest integer equal or lower than the original value.
380 ///
381 /// This behavior is preserved for negative values (unlike the basic cast).
382 ///
383 /// ```rust
384 /// # use euclid::vec2;
385 /// enum Mm {}
386 ///
387 /// assert_eq!(vec2::<_, Mm>(-0.1, -0.8).floor(), vec2::<_, Mm>(-1.0, -1.0))
388 /// ```
389 #[inline]
390 #[must_use]
391 pub fn floor(self) -> Self
392 where
393 T: Floor,
394 {
395 vec2(self.x.floor(), self.y.floor())
396 }
397
398 /// Returns the signed angle between this vector and the x axis.
399 /// Positive values counted counterclockwise, where 0 is `+x` axis, `PI/2`
400 /// is `+y` axis.
401 ///
402 /// The returned angle is between -PI and PI.
403 pub fn angle_from_x_axis(self) -> Angle<T>
404 where
405 T: Trig,
406 {
407 Angle::radians(Trig::fast_atan2(self.y, self.x))
408 }
409
410 /// Creates translation by this vector in vector units.
411 #[inline]
412 pub fn to_transform(self) -> Transform2D<T, U, U>
413 where
414 T: Zero + One,
415 {
416 Transform2D::translation(self.x, self.y)
417 }
418}
419
420impl<T, U> Vector2D<T, U>
421where
422 T: Copy + Mul<T, Output = T> + Add<T, Output = T>,
423{
424 /// Returns the vector's length squared.
425 #[inline]
426 pub fn square_length(self) -> T {
427 self.x * self.x + self.y * self.y
428 }
429
430 /// Returns this vector projected onto another one.
431 ///
432 /// Projecting onto a nil vector will cause a division by zero.
433 #[inline]
434 pub fn project_onto_vector(self, onto: Self) -> Self
435 where
436 T: Sub<T, Output = T> + Div<T, Output = T>,
437 {
438 onto * (self.dot(onto) / onto.square_length())
439 }
440
441 /// Returns the signed angle between this vector and another vector.
442 ///
443 /// The returned angle is between -PI and PI.
444 pub fn angle_to(self, other: Self) -> Angle<T>
445 where
446 T: Sub<Output = T> + Trig,
447 {
448 Angle::radians(Trig::fast_atan2(self.cross(other), self.dot(other)))
449 }
450}
451
452impl<T: Float, U> Vector2D<T, U> {
453 /// Return the normalized vector even if the length is larger than the max value of Float.
454 #[inline]
455 #[must_use]
456 pub fn robust_normalize(self) -> Self {
457 let length: T = self.length();
458 if length.is_infinite() {
459 let scaled: Vector2D = self / T::max_value();
460 scaled / scaled.length()
461 } else {
462 self / length
463 }
464 }
465
466 /// Returns true if all members are finite.
467 #[inline]
468 pub fn is_finite(self) -> bool {
469 self.x.is_finite() && self.y.is_finite()
470 }
471}
472
473impl<T: Real, U> Vector2D<T, U> {
474 /// Returns the vector length.
475 #[inline]
476 pub fn length(self) -> T {
477 self.square_length().sqrt()
478 }
479
480 /// Returns the vector with length of one unit.
481 #[inline]
482 #[must_use]
483 pub fn normalize(self) -> Self {
484 self / self.length()
485 }
486
487 /// Returns the vector with length of one unit.
488 ///
489 /// Unlike [`Vector2D::normalize`](#method.normalize), this returns None in the case that the
490 /// length of the vector is zero.
491 #[inline]
492 #[must_use]
493 pub fn try_normalize(self) -> Option<Self> {
494 let len = self.length();
495 if len == T::zero() {
496 None
497 } else {
498 Some(self / len)
499 }
500 }
501
502 /// Return this vector scaled to fit the provided length.
503 #[inline]
504 pub fn with_length(self, length: T) -> Self {
505 self.normalize() * length
506 }
507
508 /// Return this vector capped to a maximum length.
509 #[inline]
510 pub fn with_max_length(self, max_length: T) -> Self {
511 let square_length = self.square_length();
512 if square_length > max_length * max_length {
513 return self * (max_length / square_length.sqrt());
514 }
515
516 self
517 }
518
519 /// Return this vector with a minimum length applied.
520 #[inline]
521 pub fn with_min_length(self, min_length: T) -> Self {
522 let square_length = self.square_length();
523 if square_length < min_length * min_length {
524 return self * (min_length / square_length.sqrt());
525 }
526
527 self
528 }
529
530 /// Return this vector with minimum and maximum lengths applied.
531 #[inline]
532 pub fn clamp_length(self, min: T, max: T) -> Self {
533 debug_assert!(min <= max);
534 self.with_min_length(min).with_max_length(max)
535 }
536}
537
538impl<T, U> Vector2D<T, U>
539where
540 T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
541{
542 /// Linearly interpolate each component between this vector and another vector.
543 ///
544 /// # Example
545 ///
546 /// ```rust
547 /// use euclid::vec2;
548 /// use euclid::default::Vector2D;
549 ///
550 /// let from: Vector2D<_> = vec2(0.0, 10.0);
551 /// let to: Vector2D<_> = vec2(8.0, -4.0);
552 ///
553 /// assert_eq!(from.lerp(to, -1.0), vec2(-8.0, 24.0));
554 /// assert_eq!(from.lerp(to, 0.0), vec2( 0.0, 10.0));
555 /// assert_eq!(from.lerp(to, 0.5), vec2( 4.0, 3.0));
556 /// assert_eq!(from.lerp(to, 1.0), vec2( 8.0, -4.0));
557 /// assert_eq!(from.lerp(to, 2.0), vec2(16.0, -18.0));
558 /// ```
559 #[inline]
560 pub fn lerp(self, other: Self, t: T) -> Self {
561 let one_t = T::one() - t;
562 self * one_t + other * t
563 }
564
565 /// Returns a reflection vector using an incident ray and a surface normal.
566 #[inline]
567 pub fn reflect(self, normal: Self) -> Self {
568 let two = T::one() + T::one();
569 self - normal * two * self.dot(normal)
570 }
571}
572
573impl<T: PartialOrd, U> Vector2D<T, U> {
574 /// Returns the vector each component of which are minimum of this vector and another.
575 #[inline]
576 pub fn min(self, other: Self) -> Self {
577 vec2(min(self.x, other.x), min(self.y, other.y))
578 }
579
580 /// Returns the vector each component of which are maximum of this vector and another.
581 #[inline]
582 pub fn max(self, other: Self) -> Self {
583 vec2(max(self.x, other.x), max(self.y, other.y))
584 }
585
586 /// Returns the vector each component of which is clamped by corresponding
587 /// components of `start` and `end`.
588 ///
589 /// Shortcut for `self.max(start).min(end)`.
590 #[inline]
591 pub fn clamp(self, start: Self, end: Self) -> Self
592 where
593 T: Copy,
594 {
595 self.max(start).min(end)
596 }
597
598 /// Returns vector with results of "greater than" operation on each component.
599 #[inline]
600 pub fn greater_than(self, other: Self) -> BoolVector2D {
601 BoolVector2D {
602 x: self.x > other.x,
603 y: self.y > other.y,
604 }
605 }
606
607 /// Returns vector with results of "lower than" operation on each component.
608 #[inline]
609 pub fn lower_than(self, other: Self) -> BoolVector2D {
610 BoolVector2D {
611 x: self.x < other.x,
612 y: self.y < other.y,
613 }
614 }
615}
616
617impl<T: PartialEq, U> Vector2D<T, U> {
618 /// Returns vector with results of "equal" operation on each component.
619 #[inline]
620 pub fn equal(self, other: Self) -> BoolVector2D {
621 BoolVector2D {
622 x: self.x == other.x,
623 y: self.y == other.y,
624 }
625 }
626
627 /// Returns vector with results of "not equal" operation on each component.
628 #[inline]
629 pub fn not_equal(self, other: Self) -> BoolVector2D {
630 BoolVector2D {
631 x: self.x != other.x,
632 y: self.y != other.y,
633 }
634 }
635}
636
637impl<T: NumCast + Copy, U> Vector2D<T, U> {
638 /// Cast from one numeric representation to another, preserving the units.
639 ///
640 /// When casting from floating vector to integer coordinates, the decimals are truncated
641 /// as one would expect from a simple cast, but this behavior does not always make sense
642 /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
643 #[inline]
644 pub fn cast<NewT: NumCast>(self) -> Vector2D<NewT, U> {
645 self.try_cast().unwrap()
646 }
647
648 /// Fallible cast from one numeric representation to another, preserving the units.
649 ///
650 /// When casting from floating vector to integer coordinates, the decimals are truncated
651 /// as one would expect from a simple cast, but this behavior does not always make sense
652 /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
653 pub fn try_cast<NewT: NumCast>(self) -> Option<Vector2D<NewT, U>> {
654 match (NumCast::from(self.x), NumCast::from(self.y)) {
655 (Some(x), Some(y)) => Some(Vector2D::new(x, y)),
656 _ => None,
657 }
658 }
659
660 // Convenience functions for common casts.
661
662 /// Cast into an `f32` vector.
663 #[inline]
664 pub fn to_f32(self) -> Vector2D<f32, U> {
665 self.cast()
666 }
667
668 /// Cast into an `f64` vector.
669 #[inline]
670 pub fn to_f64(self) -> Vector2D<f64, U> {
671 self.cast()
672 }
673
674 /// Cast into an `usize` vector, truncating decimals if any.
675 ///
676 /// When casting from floating vector vectors, it is worth considering whether
677 /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
678 /// the desired conversion behavior.
679 #[inline]
680 pub fn to_usize(self) -> Vector2D<usize, U> {
681 self.cast()
682 }
683
684 /// Cast into an `u32` vector, truncating decimals if any.
685 ///
686 /// When casting from floating vector vectors, it is worth considering whether
687 /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
688 /// the desired conversion behavior.
689 #[inline]
690 pub fn to_u32(self) -> Vector2D<u32, U> {
691 self.cast()
692 }
693
694 /// Cast into an i32 vector, truncating decimals if any.
695 ///
696 /// When casting from floating vector vectors, it is worth considering whether
697 /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
698 /// the desired conversion behavior.
699 #[inline]
700 pub fn to_i32(self) -> Vector2D<i32, U> {
701 self.cast()
702 }
703
704 /// Cast into an i64 vector, truncating decimals if any.
705 ///
706 /// When casting from floating vector vectors, it is worth considering whether
707 /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
708 /// the desired conversion behavior.
709 #[inline]
710 pub fn to_i64(self) -> Vector2D<i64, U> {
711 self.cast()
712 }
713}
714
715impl<T: Neg, U> Neg for Vector2D<T, U> {
716 type Output = Vector2D<T::Output, U>;
717
718 #[inline]
719 fn neg(self) -> Self::Output {
720 vec2(-self.x, -self.y)
721 }
722}
723
724impl<T: Add, U> Add for Vector2D<T, U> {
725 type Output = Vector2D<T::Output, U>;
726
727 #[inline]
728 fn add(self, other: Self) -> Self::Output {
729 Vector2D::new(self.x + other.x, self.y + other.y)
730 }
731}
732
733impl<T: Add + Copy, U> Add<&Self> for Vector2D<T, U> {
734 type Output = Vector2D<T::Output, U>;
735
736 #[inline]
737 fn add(self, other: &Self) -> Self::Output {
738 Vector2D::new(self.x + other.x, self.y + other.y)
739 }
740}
741
742impl<T: Add<Output = T> + Zero, U> Sum for Vector2D<T, U> {
743 fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
744 iter.fold(Self::zero(), f:Add::add)
745 }
746}
747
748impl<'a, T: 'a + Add<Output = T> + Copy + Zero, U: 'a> Sum<&'a Self> for Vector2D<T, U> {
749 fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
750 iter.fold(Self::zero(), f:Add::add)
751 }
752}
753
754impl<T: Copy + Add<T, Output = T>, U> AddAssign for Vector2D<T, U> {
755 #[inline]
756 fn add_assign(&mut self, other: Self) {
757 *self = *self + other
758 }
759}
760
761impl<T: Sub, U> Sub for Vector2D<T, U> {
762 type Output = Vector2D<T::Output, U>;
763
764 #[inline]
765 fn sub(self, other: Self) -> Self::Output {
766 vec2(self.x - other.x, self.y - other.y)
767 }
768}
769
770impl<T: Copy + Sub<T, Output = T>, U> SubAssign<Vector2D<T, U>> for Vector2D<T, U> {
771 #[inline]
772 fn sub_assign(&mut self, other: Self) {
773 *self = *self - other
774 }
775}
776
777impl<T: Copy + Mul, U> Mul<T> for Vector2D<T, U> {
778 type Output = Vector2D<T::Output, U>;
779
780 #[inline]
781 fn mul(self, scale: T) -> Self::Output {
782 vec2(self.x * scale, self.y * scale)
783 }
784}
785
786impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Vector2D<T, U> {
787 #[inline]
788 fn mul_assign(&mut self, scale: T) {
789 *self = *self * scale
790 }
791}
792
793impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Vector2D<T, U1> {
794 type Output = Vector2D<T::Output, U2>;
795
796 #[inline]
797 fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
798 vec2(self.x * scale.0, self.y * scale.0)
799 }
800}
801
802impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Vector2D<T, U> {
803 #[inline]
804 fn mul_assign(&mut self, scale: Scale<T, U, U>) {
805 self.x *= scale.0;
806 self.y *= scale.0;
807 }
808}
809
810impl<T: Copy + Div, U> Div<T> for Vector2D<T, U> {
811 type Output = Vector2D<T::Output, U>;
812
813 #[inline]
814 fn div(self, scale: T) -> Self::Output {
815 vec2(self.x / scale, self.y / scale)
816 }
817}
818
819impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Vector2D<T, U> {
820 #[inline]
821 fn div_assign(&mut self, scale: T) {
822 *self = *self / scale
823 }
824}
825
826impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Vector2D<T, U2> {
827 type Output = Vector2D<T::Output, U1>;
828
829 #[inline]
830 fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
831 vec2(self.x / scale.0, self.y / scale.0)
832 }
833}
834
835impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Vector2D<T, U> {
836 #[inline]
837 fn div_assign(&mut self, scale: Scale<T, U, U>) {
838 self.x /= scale.0;
839 self.y /= scale.0;
840 }
841}
842
843impl<T: Round, U> Round for Vector2D<T, U> {
844 /// See [`Vector2D::round()`](#method.round)
845 #[inline]
846 fn round(self) -> Self {
847 self.round()
848 }
849}
850
851impl<T: Ceil, U> Ceil for Vector2D<T, U> {
852 /// See [`Vector2D::ceil()`](#method.ceil)
853 #[inline]
854 fn ceil(self) -> Self {
855 self.ceil()
856 }
857}
858
859impl<T: Floor, U> Floor for Vector2D<T, U> {
860 /// See [`Vector2D::floor()`](#method.floor)
861 #[inline]
862 fn floor(self) -> Self {
863 self.floor()
864 }
865}
866
867impl<T: ApproxEq<T>, U> ApproxEq<Vector2D<T, U>> for Vector2D<T, U> {
868 #[inline]
869 fn approx_epsilon() -> Self {
870 vec2(T::approx_epsilon(), T::approx_epsilon())
871 }
872
873 #[inline]
874 fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
875 self.x.approx_eq_eps(&other.x, &eps.x) && self.y.approx_eq_eps(&other.y, &eps.y)
876 }
877}
878
879impl<T, U> Into<[T; 2]> for Vector2D<T, U> {
880 fn into(self) -> [T; 2] {
881 [self.x, self.y]
882 }
883}
884
885impl<T, U> From<[T; 2]> for Vector2D<T, U> {
886 fn from([x: T, y: T]: [T; 2]) -> Self {
887 vec2(x, y)
888 }
889}
890
891impl<T, U> Into<(T, T)> for Vector2D<T, U> {
892 fn into(self) -> (T, T) {
893 (self.x, self.y)
894 }
895}
896
897impl<T, U> From<(T, T)> for Vector2D<T, U> {
898 fn from(tuple: (T, T)) -> Self {
899 vec2(x:tuple.0, y:tuple.1)
900 }
901}
902
903impl<T, U> From<Size2D<T, U>> for Vector2D<T, U> {
904 fn from(size: Size2D<T, U>) -> Self {
905 vec2(x:size.width, y:size.height)
906 }
907}
908
909/// A 3d Vector tagged with a unit.
910#[repr(C)]
911pub struct Vector3D<T, U> {
912 /// The `x` (traditionally, horizontal) coordinate.
913 pub x: T,
914 /// The `y` (traditionally, vertical) coordinate.
915 pub y: T,
916 /// The `z` (traditionally, depth) coordinate.
917 pub z: T,
918 #[doc(hidden)]
919 pub _unit: PhantomData<U>,
920}
921
922mint_vec!(Vector3D[x, y, z] = Vector3);
923
924impl<T: Copy, U> Copy for Vector3D<T, U> {}
925
926impl<T: Clone, U> Clone for Vector3D<T, U> {
927 fn clone(&self) -> Self {
928 Vector3D {
929 x: self.x.clone(),
930 y: self.y.clone(),
931 z: self.z.clone(),
932 _unit: PhantomData,
933 }
934 }
935}
936
937#[cfg(feature = "serde")]
938impl<'de, T, U> serde::Deserialize<'de> for Vector3D<T, U>
939where
940 T: serde::Deserialize<'de>,
941{
942 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
943 where
944 D: serde::Deserializer<'de>,
945 {
946 let (x, y, z) = serde::Deserialize::deserialize(deserializer)?;
947 Ok(Vector3D {
948 x,
949 y,
950 z,
951 _unit: PhantomData,
952 })
953 }
954}
955
956#[cfg(feature = "serde")]
957impl<T, U> serde::Serialize for Vector3D<T, U>
958where
959 T: serde::Serialize,
960{
961 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
962 where
963 S: serde::Serializer,
964 {
965 (&self.x, &self.y, &self.z).serialize(serializer)
966 }
967}
968
969#[cfg(feature = "bytemuck")]
970unsafe impl<T: Zeroable, U> Zeroable for Vector3D<T, U> {}
971
972#[cfg(feature = "bytemuck")]
973unsafe impl<T: Pod, U: 'static> Pod for Vector3D<T, U> {}
974
975impl<T: Eq, U> Eq for Vector3D<T, U> {}
976
977impl<T: PartialEq, U> PartialEq for Vector3D<T, U> {
978 fn eq(&self, other: &Self) -> bool {
979 self.x == other.x && self.y == other.y && self.z == other.z
980 }
981}
982
983impl<T: Hash, U> Hash for Vector3D<T, U> {
984 fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
985 self.x.hash(state:h);
986 self.y.hash(state:h);
987 self.z.hash(state:h);
988 }
989}
990
991impl<T: Zero, U> Zero for Vector3D<T, U> {
992 /// Constructor, setting all components to zero.
993 #[inline]
994 fn zero() -> Self {
995 vec3(x:Zero::zero(), y:Zero::zero(), z:Zero::zero())
996 }
997}
998
999impl<T: fmt::Debug, U> fmt::Debug for Vector3D<T, U> {
1000 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1001 f&mut DebugTuple<'_, '_>.debug_tuple(name:"")
1002 .field(&self.x)
1003 .field(&self.y)
1004 .field(&self.z)
1005 .finish()
1006 }
1007}
1008
1009impl<T: Default, U> Default for Vector3D<T, U> {
1010 fn default() -> Self {
1011 Vector3D::new(x:Default::default(), y:Default::default(), z:Default::default())
1012 }
1013}
1014
1015impl<T, U> Vector3D<T, U> {
1016 /// Constructor, setting all components to zero.
1017 #[inline]
1018 pub fn zero() -> Self
1019 where
1020 T: Zero,
1021 {
1022 vec3(Zero::zero(), Zero::zero(), Zero::zero())
1023 }
1024
1025 /// Constructor, setting all components to one.
1026 #[inline]
1027 pub fn one() -> Self
1028 where
1029 T: One,
1030 {
1031 vec3(One::one(), One::one(), One::one())
1032 }
1033
1034 /// Constructor taking scalar values directly.
1035 #[inline]
1036 pub const fn new(x: T, y: T, z: T) -> Self {
1037 Vector3D {
1038 x,
1039 y,
1040 z,
1041 _unit: PhantomData,
1042 }
1043 }
1044 /// Constructor setting all components to the same value.
1045 #[inline]
1046 pub fn splat(v: T) -> Self
1047 where
1048 T: Clone,
1049 {
1050 Vector3D {
1051 x: v.clone(),
1052 y: v.clone(),
1053 z: v,
1054 _unit: PhantomData,
1055 }
1056 }
1057
1058 /// Constructor taking properly Lengths instead of scalar values.
1059 #[inline]
1060 pub fn from_lengths(x: Length<T, U>, y: Length<T, U>, z: Length<T, U>) -> Vector3D<T, U> {
1061 vec3(x.0, y.0, z.0)
1062 }
1063
1064 /// Tag a unitless value with units.
1065 #[inline]
1066 pub fn from_untyped(p: Vector3D<T, UnknownUnit>) -> Self {
1067 vec3(p.x, p.y, p.z)
1068 }
1069
1070 /// Computes the vector with absolute values of each component.
1071 ///
1072 /// # Example
1073 ///
1074 /// ```rust
1075 /// # use std::{i32, f32};
1076 /// # use euclid::vec3;
1077 /// enum U {}
1078 ///
1079 /// assert_eq!(vec3::<_, U>(-1, 0, 2).abs(), vec3(1, 0, 2));
1080 ///
1081 /// let vec = vec3::<_, U>(f32::NAN, 0.0, -f32::MAX).abs();
1082 /// assert!(vec.x.is_nan());
1083 /// assert_eq!(vec.y, 0.0);
1084 /// assert_eq!(vec.z, f32::MAX);
1085 /// ```
1086 ///
1087 /// # Panics
1088 ///
1089 /// The behavior for each component follows the scalar type's implementation of
1090 /// `num_traits::Signed::abs`.
1091 pub fn abs(self) -> Self
1092 where
1093 T: Signed,
1094 {
1095 vec3(self.x.abs(), self.y.abs(), self.z.abs())
1096 }
1097
1098 /// Dot product.
1099 #[inline]
1100 pub fn dot(self, other: Self) -> T
1101 where
1102 T: Add<Output = T> + Mul<Output = T>,
1103 {
1104 self.x * other.x + self.y * other.y + self.z * other.z
1105 }
1106}
1107
1108impl<T: Copy, U> Vector3D<T, U> {
1109 /// Cross product.
1110 #[inline]
1111 pub fn cross(self, other: Self) -> Self
1112 where
1113 T: Sub<Output = T> + Mul<Output = T>,
1114 {
1115 vec3(
1116 self.y * other.z - self.z * other.y,
1117 self.z * other.x - self.x * other.z,
1118 self.x * other.y - self.y * other.x,
1119 )
1120 }
1121
1122 /// Returns the component-wise multiplication of the two vectors.
1123 #[inline]
1124 pub fn component_mul(self, other: Self) -> Self
1125 where
1126 T: Mul<Output = T>,
1127 {
1128 vec3(self.x * other.x, self.y * other.y, self.z * other.z)
1129 }
1130
1131 /// Returns the component-wise division of the two vectors.
1132 #[inline]
1133 pub fn component_div(self, other: Self) -> Self
1134 where
1135 T: Div<Output = T>,
1136 {
1137 vec3(self.x / other.x, self.y / other.y, self.z / other.z)
1138 }
1139
1140 /// Cast this vector into a point.
1141 ///
1142 /// Equivalent to adding this vector to the origin.
1143 #[inline]
1144 pub fn to_point(self) -> Point3D<T, U> {
1145 point3(self.x, self.y, self.z)
1146 }
1147
1148 /// Returns a 2d vector using this vector's x and y coordinates
1149 #[inline]
1150 pub fn xy(self) -> Vector2D<T, U> {
1151 vec2(self.x, self.y)
1152 }
1153
1154 /// Returns a 2d vector using this vector's x and z coordinates
1155 #[inline]
1156 pub fn xz(self) -> Vector2D<T, U> {
1157 vec2(self.x, self.z)
1158 }
1159
1160 /// Returns a 2d vector using this vector's x and z coordinates
1161 #[inline]
1162 pub fn yz(self) -> Vector2D<T, U> {
1163 vec2(self.y, self.z)
1164 }
1165
1166 /// Cast into an array with x, y and z.
1167 #[inline]
1168 pub fn to_array(self) -> [T; 3] {
1169 [self.x, self.y, self.z]
1170 }
1171
1172 /// Cast into an array with x, y, z and 0.
1173 #[inline]
1174 pub fn to_array_4d(self) -> [T; 4]
1175 where
1176 T: Zero,
1177 {
1178 [self.x, self.y, self.z, Zero::zero()]
1179 }
1180
1181 /// Cast into a tuple with x, y and z.
1182 #[inline]
1183 pub fn to_tuple(self) -> (T, T, T) {
1184 (self.x, self.y, self.z)
1185 }
1186
1187 /// Cast into a tuple with x, y, z and 0.
1188 #[inline]
1189 pub fn to_tuple_4d(self) -> (T, T, T, T)
1190 where
1191 T: Zero,
1192 {
1193 (self.x, self.y, self.z, Zero::zero())
1194 }
1195
1196 /// Drop the units, preserving only the numeric value.
1197 #[inline]
1198 pub fn to_untyped(self) -> Vector3D<T, UnknownUnit> {
1199 vec3(self.x, self.y, self.z)
1200 }
1201
1202 /// Cast the unit.
1203 #[inline]
1204 pub fn cast_unit<V>(self) -> Vector3D<T, V> {
1205 vec3(self.x, self.y, self.z)
1206 }
1207
1208 /// Convert into a 2d vector.
1209 #[inline]
1210 pub fn to_2d(self) -> Vector2D<T, U> {
1211 self.xy()
1212 }
1213
1214 /// Rounds each component to the nearest integer value.
1215 ///
1216 /// This behavior is preserved for negative values (unlike the basic cast).
1217 ///
1218 /// ```rust
1219 /// # use euclid::vec3;
1220 /// enum Mm {}
1221 ///
1222 /// assert_eq!(vec3::<_, Mm>(-0.1, -0.8, 0.4).round(), vec3::<_, Mm>(0.0, -1.0, 0.0))
1223 /// ```
1224 #[inline]
1225 #[must_use]
1226 pub fn round(self) -> Self
1227 where
1228 T: Round,
1229 {
1230 vec3(self.x.round(), self.y.round(), self.z.round())
1231 }
1232
1233 /// Rounds each component to the smallest integer equal or greater than the original value.
1234 ///
1235 /// This behavior is preserved for negative values (unlike the basic cast).
1236 ///
1237 /// ```rust
1238 /// # use euclid::vec3;
1239 /// enum Mm {}
1240 ///
1241 /// assert_eq!(vec3::<_, Mm>(-0.1, -0.8, 0.4).ceil(), vec3::<_, Mm>(0.0, 0.0, 1.0))
1242 /// ```
1243 #[inline]
1244 #[must_use]
1245 pub fn ceil(self) -> Self
1246 where
1247 T: Ceil,
1248 {
1249 vec3(self.x.ceil(), self.y.ceil(), self.z.ceil())
1250 }
1251
1252 /// Rounds each component to the biggest integer equal or lower than the original value.
1253 ///
1254 /// This behavior is preserved for negative values (unlike the basic cast).
1255 ///
1256 /// ```rust
1257 /// # use euclid::vec3;
1258 /// enum Mm {}
1259 ///
1260 /// assert_eq!(vec3::<_, Mm>(-0.1, -0.8, 0.4).floor(), vec3::<_, Mm>(-1.0, -1.0, 0.0))
1261 /// ```
1262 #[inline]
1263 #[must_use]
1264 pub fn floor(self) -> Self
1265 where
1266 T: Floor,
1267 {
1268 vec3(self.x.floor(), self.y.floor(), self.z.floor())
1269 }
1270
1271 /// Creates translation by this vector in vector units
1272 #[inline]
1273 pub fn to_transform(self) -> Transform3D<T, U, U>
1274 where
1275 T: Zero + One,
1276 {
1277 Transform3D::translation(self.x, self.y, self.z)
1278 }
1279}
1280
1281impl<T, U> Vector3D<T, U>
1282where
1283 T: Copy + Mul<T, Output = T> + Add<T, Output = T>,
1284{
1285 /// Returns the vector's length squared.
1286 #[inline]
1287 pub fn square_length(self) -> T {
1288 self.x * self.x + self.y * self.y + self.z * self.z
1289 }
1290
1291 /// Returns this vector projected onto another one.
1292 ///
1293 /// Projecting onto a nil vector will cause a division by zero.
1294 #[inline]
1295 pub fn project_onto_vector(self, onto: Self) -> Self
1296 where
1297 T: Sub<T, Output = T> + Div<T, Output = T>,
1298 {
1299 onto * (self.dot(onto) / onto.square_length())
1300 }
1301}
1302
1303impl<T: Float, U> Vector3D<T, U> {
1304 /// Return the normalized vector even if the length is larger than the max value of Float.
1305 #[inline]
1306 #[must_use]
1307 pub fn robust_normalize(self) -> Self {
1308 let length: T = self.length();
1309 if length.is_infinite() {
1310 let scaled: Vector3D = self / T::max_value();
1311 scaled / scaled.length()
1312 } else {
1313 self / length
1314 }
1315 }
1316
1317 /// Returns true if all members are finite.
1318 #[inline]
1319 pub fn is_finite(self) -> bool {
1320 self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
1321 }
1322}
1323
1324impl<T: Real, U> Vector3D<T, U> {
1325 /// Returns the positive angle between this vector and another vector.
1326 ///
1327 /// The returned angle is between 0 and PI.
1328 pub fn angle_to(self, other: Self) -> Angle<T>
1329 where
1330 T: Trig,
1331 {
1332 Angle::radians(Trig::fast_atan2(
1333 self.cross(other).length(),
1334 self.dot(other),
1335 ))
1336 }
1337
1338 /// Returns the vector length.
1339 #[inline]
1340 pub fn length(self) -> T {
1341 self.square_length().sqrt()
1342 }
1343
1344 /// Returns the vector with length of one unit
1345 #[inline]
1346 #[must_use]
1347 pub fn normalize(self) -> Self {
1348 self / self.length()
1349 }
1350
1351 /// Returns the vector with length of one unit.
1352 ///
1353 /// Unlike [`Vector2D::normalize`](#method.normalize), this returns None in the case that the
1354 /// length of the vector is zero.
1355 #[inline]
1356 #[must_use]
1357 pub fn try_normalize(self) -> Option<Self> {
1358 let len = self.length();
1359 if len == T::zero() {
1360 None
1361 } else {
1362 Some(self / len)
1363 }
1364 }
1365
1366 /// Return this vector capped to a maximum length.
1367 #[inline]
1368 pub fn with_max_length(self, max_length: T) -> Self {
1369 let square_length = self.square_length();
1370 if square_length > max_length * max_length {
1371 return self * (max_length / square_length.sqrt());
1372 }
1373
1374 self
1375 }
1376
1377 /// Return this vector with a minimum length applied.
1378 #[inline]
1379 pub fn with_min_length(self, min_length: T) -> Self {
1380 let square_length = self.square_length();
1381 if square_length < min_length * min_length {
1382 return self * (min_length / square_length.sqrt());
1383 }
1384
1385 self
1386 }
1387
1388 /// Return this vector with minimum and maximum lengths applied.
1389 #[inline]
1390 pub fn clamp_length(self, min: T, max: T) -> Self {
1391 debug_assert!(min <= max);
1392 self.with_min_length(min).with_max_length(max)
1393 }
1394}
1395
1396impl<T, U> Vector3D<T, U>
1397where
1398 T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
1399{
1400 /// Linearly interpolate each component between this vector and another vector.
1401 ///
1402 /// # Example
1403 ///
1404 /// ```rust
1405 /// use euclid::vec3;
1406 /// use euclid::default::Vector3D;
1407 ///
1408 /// let from: Vector3D<_> = vec3(0.0, 10.0, -1.0);
1409 /// let to: Vector3D<_> = vec3(8.0, -4.0, 0.0);
1410 ///
1411 /// assert_eq!(from.lerp(to, -1.0), vec3(-8.0, 24.0, -2.0));
1412 /// assert_eq!(from.lerp(to, 0.0), vec3( 0.0, 10.0, -1.0));
1413 /// assert_eq!(from.lerp(to, 0.5), vec3( 4.0, 3.0, -0.5));
1414 /// assert_eq!(from.lerp(to, 1.0), vec3( 8.0, -4.0, 0.0));
1415 /// assert_eq!(from.lerp(to, 2.0), vec3(16.0, -18.0, 1.0));
1416 /// ```
1417 #[inline]
1418 pub fn lerp(self, other: Self, t: T) -> Self {
1419 let one_t = T::one() - t;
1420 self * one_t + other * t
1421 }
1422
1423 /// Returns a reflection vector using an incident ray and a surface normal.
1424 #[inline]
1425 pub fn reflect(self, normal: Self) -> Self {
1426 let two = T::one() + T::one();
1427 self - normal * two * self.dot(normal)
1428 }
1429}
1430
1431impl<T: PartialOrd, U> Vector3D<T, U> {
1432 /// Returns the vector each component of which are minimum of this vector and another.
1433 #[inline]
1434 pub fn min(self, other: Self) -> Self {
1435 vec3(
1436 min(self.x, other.x),
1437 min(self.y, other.y),
1438 min(self.z, other.z),
1439 )
1440 }
1441
1442 /// Returns the vector each component of which are maximum of this vector and another.
1443 #[inline]
1444 pub fn max(self, other: Self) -> Self {
1445 vec3(
1446 max(self.x, other.x),
1447 max(self.y, other.y),
1448 max(self.z, other.z),
1449 )
1450 }
1451
1452 /// Returns the vector each component of which is clamped by corresponding
1453 /// components of `start` and `end`.
1454 ///
1455 /// Shortcut for `self.max(start).min(end)`.
1456 #[inline]
1457 pub fn clamp(self, start: Self, end: Self) -> Self
1458 where
1459 T: Copy,
1460 {
1461 self.max(start).min(end)
1462 }
1463
1464 /// Returns vector with results of "greater than" operation on each component.
1465 #[inline]
1466 pub fn greater_than(self, other: Self) -> BoolVector3D {
1467 BoolVector3D {
1468 x: self.x > other.x,
1469 y: self.y > other.y,
1470 z: self.z > other.z,
1471 }
1472 }
1473
1474 /// Returns vector with results of "lower than" operation on each component.
1475 #[inline]
1476 pub fn lower_than(self, other: Self) -> BoolVector3D {
1477 BoolVector3D {
1478 x: self.x < other.x,
1479 y: self.y < other.y,
1480 z: self.z < other.z,
1481 }
1482 }
1483}
1484
1485impl<T: PartialEq, U> Vector3D<T, U> {
1486 /// Returns vector with results of "equal" operation on each component.
1487 #[inline]
1488 pub fn equal(self, other: Self) -> BoolVector3D {
1489 BoolVector3D {
1490 x: self.x == other.x,
1491 y: self.y == other.y,
1492 z: self.z == other.z,
1493 }
1494 }
1495
1496 /// Returns vector with results of "not equal" operation on each component.
1497 #[inline]
1498 pub fn not_equal(self, other: Self) -> BoolVector3D {
1499 BoolVector3D {
1500 x: self.x != other.x,
1501 y: self.y != other.y,
1502 z: self.z != other.z,
1503 }
1504 }
1505}
1506
1507impl<T: NumCast + Copy, U> Vector3D<T, U> {
1508 /// Cast from one numeric representation to another, preserving the units.
1509 ///
1510 /// When casting from floating vector to integer coordinates, the decimals are truncated
1511 /// as one would expect from a simple cast, but this behavior does not always make sense
1512 /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
1513 #[inline]
1514 pub fn cast<NewT: NumCast>(self) -> Vector3D<NewT, U> {
1515 self.try_cast().unwrap()
1516 }
1517
1518 /// Fallible cast from one numeric representation to another, preserving the units.
1519 ///
1520 /// When casting from floating vector to integer coordinates, the decimals are truncated
1521 /// as one would expect from a simple cast, but this behavior does not always make sense
1522 /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
1523 pub fn try_cast<NewT: NumCast>(self) -> Option<Vector3D<NewT, U>> {
1524 match (
1525 NumCast::from(self.x),
1526 NumCast::from(self.y),
1527 NumCast::from(self.z),
1528 ) {
1529 (Some(x), Some(y), Some(z)) => Some(vec3(x, y, z)),
1530 _ => None,
1531 }
1532 }
1533
1534 // Convenience functions for common casts.
1535
1536 /// Cast into an `f32` vector.
1537 #[inline]
1538 pub fn to_f32(self) -> Vector3D<f32, U> {
1539 self.cast()
1540 }
1541
1542 /// Cast into an `f64` vector.
1543 #[inline]
1544 pub fn to_f64(self) -> Vector3D<f64, U> {
1545 self.cast()
1546 }
1547
1548 /// Cast into an `usize` vector, truncating decimals if any.
1549 ///
1550 /// When casting from floating vector vectors, it is worth considering whether
1551 /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
1552 /// the desired conversion behavior.
1553 #[inline]
1554 pub fn to_usize(self) -> Vector3D<usize, U> {
1555 self.cast()
1556 }
1557
1558 /// Cast into an `u32` vector, truncating decimals if any.
1559 ///
1560 /// When casting from floating vector vectors, it is worth considering whether
1561 /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
1562 /// the desired conversion behavior.
1563 #[inline]
1564 pub fn to_u32(self) -> Vector3D<u32, U> {
1565 self.cast()
1566 }
1567
1568 /// Cast into an `i32` vector, truncating decimals if any.
1569 ///
1570 /// When casting from floating vector vectors, it is worth considering whether
1571 /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
1572 /// the desired conversion behavior.
1573 #[inline]
1574 pub fn to_i32(self) -> Vector3D<i32, U> {
1575 self.cast()
1576 }
1577
1578 /// Cast into an `i64` vector, truncating decimals if any.
1579 ///
1580 /// When casting from floating vector vectors, it is worth considering whether
1581 /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
1582 /// the desired conversion behavior.
1583 #[inline]
1584 pub fn to_i64(self) -> Vector3D<i64, U> {
1585 self.cast()
1586 }
1587}
1588
1589impl<T: Neg, U> Neg for Vector3D<T, U> {
1590 type Output = Vector3D<T::Output, U>;
1591
1592 #[inline]
1593 fn neg(self) -> Self::Output {
1594 vec3(-self.x, -self.y, -self.z)
1595 }
1596}
1597
1598impl<T: Add, U> Add for Vector3D<T, U> {
1599 type Output = Vector3D<T::Output, U>;
1600
1601 #[inline]
1602 fn add(self, other: Self) -> Self::Output {
1603 vec3(self.x + other.x, self.y + other.y, self.z + other.z)
1604 }
1605}
1606
1607impl<'a, T: 'a + Add + Copy, U: 'a> Add<&Self> for Vector3D<T, U> {
1608 type Output = Vector3D<T::Output, U>;
1609
1610 #[inline]
1611 fn add(self, other: &Self) -> Self::Output {
1612 vec3(self.x + other.x, self.y + other.y, self.z + other.z)
1613 }
1614}
1615
1616impl<T: Add<Output = T> + Zero, U> Sum for Vector3D<T, U> {
1617 fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
1618 iter.fold(Self::zero(), f:Add::add)
1619 }
1620}
1621
1622impl<'a, T: 'a + Add<Output = T> + Copy + Zero, U: 'a> Sum<&'a Self> for Vector3D<T, U> {
1623 fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
1624 iter.fold(Self::zero(), f:Add::add)
1625 }
1626}
1627
1628impl<T: Copy + Add<T, Output = T>, U> AddAssign for Vector3D<T, U> {
1629 #[inline]
1630 fn add_assign(&mut self, other: Self) {
1631 *self = *self + other
1632 }
1633}
1634
1635impl<T: Sub, U> Sub for Vector3D<T, U> {
1636 type Output = Vector3D<T::Output, U>;
1637
1638 #[inline]
1639 fn sub(self, other: Self) -> Self::Output {
1640 vec3(self.x - other.x, self.y - other.y, self.z - other.z)
1641 }
1642}
1643
1644impl<T: Copy + Sub<T, Output = T>, U> SubAssign<Vector3D<T, U>> for Vector3D<T, U> {
1645 #[inline]
1646 fn sub_assign(&mut self, other: Self) {
1647 *self = *self - other
1648 }
1649}
1650
1651impl<T: Copy + Mul, U> Mul<T> for Vector3D<T, U> {
1652 type Output = Vector3D<T::Output, U>;
1653
1654 #[inline]
1655 fn mul(self, scale: T) -> Self::Output {
1656 vec3(
1657 self.x * scale,
1658 self.y * scale,
1659 self.z * scale,
1660 )
1661 }
1662}
1663
1664impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Vector3D<T, U> {
1665 #[inline]
1666 fn mul_assign(&mut self, scale: T) {
1667 *self = *self * scale
1668 }
1669}
1670
1671impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Vector3D<T, U1> {
1672 type Output = Vector3D<T::Output, U2>;
1673
1674 #[inline]
1675 fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
1676 vec3(
1677 self.x * scale.0,
1678 self.y * scale.0,
1679 self.z * scale.0,
1680 )
1681 }
1682}
1683
1684impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Vector3D<T, U> {
1685 #[inline]
1686 fn mul_assign(&mut self, scale: Scale<T, U, U>) {
1687 self.x *= scale.0;
1688 self.y *= scale.0;
1689 self.z *= scale.0;
1690 }
1691}
1692
1693impl<T: Copy + Div, U> Div<T> for Vector3D<T, U> {
1694 type Output = Vector3D<T::Output, U>;
1695
1696 #[inline]
1697 fn div(self, scale: T) -> Self::Output {
1698 vec3(
1699 self.x / scale,
1700 self.y / scale,
1701 self.z / scale,
1702 )
1703 }
1704}
1705
1706impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Vector3D<T, U> {
1707 #[inline]
1708 fn div_assign(&mut self, scale: T) {
1709 *self = *self / scale
1710 }
1711}
1712
1713impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Vector3D<T, U2> {
1714 type Output = Vector3D<T::Output, U1>;
1715
1716 #[inline]
1717 fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
1718 vec3(
1719 self.x / scale.0,
1720 self.y / scale.0,
1721 self.z / scale.0,
1722 )
1723 }
1724}
1725
1726impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Vector3D<T, U> {
1727 #[inline]
1728 fn div_assign(&mut self, scale: Scale<T, U, U>) {
1729 self.x /= scale.0;
1730 self.y /= scale.0;
1731 self.z /= scale.0;
1732 }
1733}
1734
1735impl<T: Round, U> Round for Vector3D<T, U> {
1736 /// See [`Vector3D::round()`](#method.round)
1737 #[inline]
1738 fn round(self) -> Self {
1739 self.round()
1740 }
1741}
1742
1743impl<T: Ceil, U> Ceil for Vector3D<T, U> {
1744 /// See [`Vector3D::ceil()`](#method.ceil)
1745 #[inline]
1746 fn ceil(self) -> Self {
1747 self.ceil()
1748 }
1749}
1750
1751impl<T: Floor, U> Floor for Vector3D<T, U> {
1752 /// See [`Vector3D::floor()`](#method.floor)
1753 #[inline]
1754 fn floor(self) -> Self {
1755 self.floor()
1756 }
1757}
1758
1759impl<T: ApproxEq<T>, U> ApproxEq<Vector3D<T, U>> for Vector3D<T, U> {
1760 #[inline]
1761 fn approx_epsilon() -> Self {
1762 vec3(
1763 T::approx_epsilon(),
1764 T::approx_epsilon(),
1765 T::approx_epsilon(),
1766 )
1767 }
1768
1769 #[inline]
1770 fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
1771 self.x.approx_eq_eps(&other.x, &eps.x)
1772 && self.y.approx_eq_eps(&other.y, &eps.y)
1773 && self.z.approx_eq_eps(&other.z, &eps.z)
1774 }
1775}
1776
1777impl<T, U> Into<[T; 3]> for Vector3D<T, U> {
1778 fn into(self) -> [T; 3] {
1779 [self.x, self.y, self.z]
1780 }
1781}
1782
1783impl<T, U> From<[T; 3]> for Vector3D<T, U> {
1784 fn from([x: T, y: T, z: T]: [T; 3]) -> Self {
1785 vec3(x, y, z)
1786 }
1787}
1788
1789impl<T, U> Into<(T, T, T)> for Vector3D<T, U> {
1790 fn into(self) -> (T, T, T) {
1791 (self.x, self.y, self.z)
1792 }
1793}
1794
1795impl<T, U> From<(T, T, T)> for Vector3D<T, U> {
1796 fn from(tuple: (T, T, T)) -> Self {
1797 vec3(x:tuple.0, y:tuple.1, z:tuple.2)
1798 }
1799}
1800
1801/// A 2d vector of booleans, useful for component-wise logic operations.
1802#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1803pub struct BoolVector2D {
1804 pub x: bool,
1805 pub y: bool,
1806}
1807
1808/// A 3d vector of booleans, useful for component-wise logic operations.
1809#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1810pub struct BoolVector3D {
1811 pub x: bool,
1812 pub y: bool,
1813 pub z: bool,
1814}
1815
1816impl BoolVector2D {
1817 /// Returns `true` if all components are `true` and `false` otherwise.
1818 #[inline]
1819 pub fn all(self) -> bool {
1820 self.x && self.y
1821 }
1822
1823 /// Returns `true` if any component are `true` and `false` otherwise.
1824 #[inline]
1825 pub fn any(self) -> bool {
1826 self.x || self.y
1827 }
1828
1829 /// Returns `true` if all components are `false` and `false` otherwise. Negation of `any()`.
1830 #[inline]
1831 pub fn none(self) -> bool {
1832 !self.any()
1833 }
1834
1835 /// Returns new vector with by-component AND operation applied.
1836 #[inline]
1837 pub fn and(self, other: Self) -> Self {
1838 BoolVector2D {
1839 x: self.x && other.x,
1840 y: self.y && other.y,
1841 }
1842 }
1843
1844 /// Returns new vector with by-component OR operation applied.
1845 #[inline]
1846 pub fn or(self, other: Self) -> Self {
1847 BoolVector2D {
1848 x: self.x || other.x,
1849 y: self.y || other.y,
1850 }
1851 }
1852
1853 /// Returns new vector with results of negation operation on each component.
1854 #[inline]
1855 pub fn not(self) -> Self {
1856 BoolVector2D {
1857 x: !self.x,
1858 y: !self.y,
1859 }
1860 }
1861
1862 /// Returns point, each component of which or from `a`, or from `b` depending on truly value
1863 /// of corresponding vector component. `true` selects value from `a` and `false` from `b`.
1864 #[inline]
1865 pub fn select_point<T, U>(self, a: Point2D<T, U>, b: Point2D<T, U>) -> Point2D<T, U> {
1866 point2(
1867 if self.x { a.x } else { b.x },
1868 if self.y { a.y } else { b.y },
1869 )
1870 }
1871
1872 /// Returns vector, each component of which or from `a`, or from `b` depending on truly value
1873 /// of corresponding vector component. `true` selects value from `a` and `false` from `b`.
1874 #[inline]
1875 pub fn select_vector<T, U>(self, a: Vector2D<T, U>, b: Vector2D<T, U>) -> Vector2D<T, U> {
1876 vec2(
1877 if self.x { a.x } else { b.x },
1878 if self.y { a.y } else { b.y },
1879 )
1880 }
1881
1882 /// Returns size, each component of which or from `a`, or from `b` depending on truly value
1883 /// of corresponding vector component. `true` selects value from `a` and `false` from `b`.
1884 #[inline]
1885 pub fn select_size<T, U>(self, a: Size2D<T, U>, b: Size2D<T, U>) -> Size2D<T, U> {
1886 size2(
1887 if self.x { a.width } else { b.width },
1888 if self.y { a.height } else { b.height },
1889 )
1890 }
1891}
1892
1893impl BoolVector3D {
1894 /// Returns `true` if all components are `true` and `false` otherwise.
1895 #[inline]
1896 pub fn all(self) -> bool {
1897 self.x && self.y && self.z
1898 }
1899
1900 /// Returns `true` if any component are `true` and `false` otherwise.
1901 #[inline]
1902 pub fn any(self) -> bool {
1903 self.x || self.y || self.z
1904 }
1905
1906 /// Returns `true` if all components are `false` and `false` otherwise. Negation of `any()`.
1907 #[inline]
1908 pub fn none(self) -> bool {
1909 !self.any()
1910 }
1911
1912 /// Returns new vector with by-component AND operation applied.
1913 #[inline]
1914 pub fn and(self, other: Self) -> Self {
1915 BoolVector3D {
1916 x: self.x && other.x,
1917 y: self.y && other.y,
1918 z: self.z && other.z,
1919 }
1920 }
1921
1922 /// Returns new vector with by-component OR operation applied.
1923 #[inline]
1924 pub fn or(self, other: Self) -> Self {
1925 BoolVector3D {
1926 x: self.x || other.x,
1927 y: self.y || other.y,
1928 z: self.z || other.z,
1929 }
1930 }
1931
1932 /// Returns new vector with results of negation operation on each component.
1933 #[inline]
1934 pub fn not(self) -> Self {
1935 BoolVector3D {
1936 x: !self.x,
1937 y: !self.y,
1938 z: !self.z,
1939 }
1940 }
1941
1942 /// Returns point, each component of which or from `a`, or from `b` depending on truly value
1943 /// of corresponding vector component. `true` selects value from `a` and `false` from `b`.
1944 #[inline]
1945 pub fn select_point<T, U>(self, a: Point3D<T, U>, b: Point3D<T, U>) -> Point3D<T, U> {
1946 point3(
1947 if self.x { a.x } else { b.x },
1948 if self.y { a.y } else { b.y },
1949 if self.z { a.z } else { b.z },
1950 )
1951 }
1952
1953 /// Returns vector, each component of which or from `a`, or from `b` depending on truly value
1954 /// of corresponding vector component. `true` selects value from `a` and `false` from `b`.
1955 #[inline]
1956 pub fn select_vector<T, U>(self, a: Vector3D<T, U>, b: Vector3D<T, U>) -> Vector3D<T, U> {
1957 vec3(
1958 if self.x { a.x } else { b.x },
1959 if self.y { a.y } else { b.y },
1960 if self.z { a.z } else { b.z },
1961 )
1962 }
1963
1964 /// Returns size, each component of which or from `a`, or from `b` depending on truly value
1965 /// of corresponding vector component. `true` selects value from `a` and `false` from `b`.
1966 #[inline]
1967 #[must_use]
1968 pub fn select_size<T, U>(self, a: Size3D<T, U>, b: Size3D<T, U>) -> Size3D<T, U> {
1969 size3(
1970 if self.x { a.width } else { b.width },
1971 if self.y { a.height } else { b.height },
1972 if self.z { a.depth } else { b.depth },
1973 )
1974 }
1975
1976 /// Returns a 2d vector using this vector's x and y coordinates.
1977 #[inline]
1978 pub fn xy(self) -> BoolVector2D {
1979 BoolVector2D {
1980 x: self.x,
1981 y: self.y,
1982 }
1983 }
1984
1985 /// Returns a 2d vector using this vector's x and z coordinates.
1986 #[inline]
1987 pub fn xz(self) -> BoolVector2D {
1988 BoolVector2D {
1989 x: self.x,
1990 y: self.z,
1991 }
1992 }
1993
1994 /// Returns a 2d vector using this vector's y and z coordinates.
1995 #[inline]
1996 pub fn yz(self) -> BoolVector2D {
1997 BoolVector2D {
1998 x: self.y,
1999 y: self.z,
2000 }
2001 }
2002}
2003
2004/// Convenience constructor.
2005#[inline]
2006pub const fn vec2<T, U>(x: T, y: T) -> Vector2D<T, U> {
2007 Vector2D {
2008 x,
2009 y,
2010 _unit: PhantomData,
2011 }
2012}
2013
2014/// Convenience constructor.
2015#[inline]
2016pub const fn vec3<T, U>(x: T, y: T, z: T) -> Vector3D<T, U> {
2017 Vector3D {
2018 x,
2019 y,
2020 z,
2021 _unit: PhantomData,
2022 }
2023}
2024
2025/// Shorthand for `BoolVector2D { x, y }`.
2026#[inline]
2027pub const fn bvec2(x: bool, y: bool) -> BoolVector2D {
2028 BoolVector2D { x, y }
2029}
2030
2031/// Shorthand for `BoolVector3D { x, y, z }`.
2032#[inline]
2033pub const fn bvec3(x: bool, y: bool, z: bool) -> BoolVector3D {
2034 BoolVector3D { x, y, z }
2035}
2036
2037#[cfg(test)]
2038mod vector2d {
2039 use crate::scale::Scale;
2040 use crate::{default, vec2};
2041
2042 #[cfg(feature = "mint")]
2043 use mint;
2044 type Vec2 = default::Vector2D<f32>;
2045
2046 #[test]
2047 pub fn test_scalar_mul() {
2048 let p1: Vec2 = vec2(3.0, 5.0);
2049
2050 let result = p1 * 5.0;
2051
2052 assert_eq!(result, Vec2::new(15.0, 25.0));
2053 }
2054
2055 #[test]
2056 pub fn test_dot() {
2057 let p1: Vec2 = vec2(2.0, 7.0);
2058 let p2: Vec2 = vec2(13.0, 11.0);
2059 assert_eq!(p1.dot(p2), 103.0);
2060 }
2061
2062 #[test]
2063 pub fn test_cross() {
2064 let p1: Vec2 = vec2(4.0, 7.0);
2065 let p2: Vec2 = vec2(13.0, 8.0);
2066 let r = p1.cross(p2);
2067 assert_eq!(r, -59.0);
2068 }
2069
2070 #[test]
2071 pub fn test_normalize() {
2072 use std::f32;
2073
2074 let p0: Vec2 = Vec2::zero();
2075 let p1: Vec2 = vec2(4.0, 0.0);
2076 let p2: Vec2 = vec2(3.0, -4.0);
2077 assert!(p0.normalize().x.is_nan() && p0.normalize().y.is_nan());
2078 assert_eq!(p1.normalize(), vec2(1.0, 0.0));
2079 assert_eq!(p2.normalize(), vec2(0.6, -0.8));
2080
2081 let p3: Vec2 = vec2(::std::f32::MAX, ::std::f32::MAX);
2082 assert_ne!(
2083 p3.normalize(),
2084 vec2(1.0 / 2.0f32.sqrt(), 1.0 / 2.0f32.sqrt())
2085 );
2086 assert_eq!(
2087 p3.robust_normalize(),
2088 vec2(1.0 / 2.0f32.sqrt(), 1.0 / 2.0f32.sqrt())
2089 );
2090
2091 let p4: Vec2 = Vec2::zero();
2092 assert!(p4.try_normalize().is_none());
2093 let p5: Vec2 = Vec2::new(f32::MIN_POSITIVE, f32::MIN_POSITIVE);
2094 assert!(p5.try_normalize().is_none());
2095
2096 let p6: Vec2 = vec2(4.0, 0.0);
2097 let p7: Vec2 = vec2(3.0, -4.0);
2098 assert_eq!(p6.try_normalize().unwrap(), vec2(1.0, 0.0));
2099 assert_eq!(p7.try_normalize().unwrap(), vec2(0.6, -0.8));
2100 }
2101
2102 #[test]
2103 pub fn test_min() {
2104 let p1: Vec2 = vec2(1.0, 3.0);
2105 let p2: Vec2 = vec2(2.0, 2.0);
2106
2107 let result = p1.min(p2);
2108
2109 assert_eq!(result, vec2(1.0, 2.0));
2110 }
2111
2112 #[test]
2113 pub fn test_max() {
2114 let p1: Vec2 = vec2(1.0, 3.0);
2115 let p2: Vec2 = vec2(2.0, 2.0);
2116
2117 let result = p1.max(p2);
2118
2119 assert_eq!(result, vec2(2.0, 3.0));
2120 }
2121
2122 #[test]
2123 pub fn test_angle_from_x_axis() {
2124 use crate::approxeq::ApproxEq;
2125 use core::f32::consts::FRAC_PI_2;
2126
2127 let right: Vec2 = vec2(10.0, 0.0);
2128 let down: Vec2 = vec2(0.0, 4.0);
2129 let up: Vec2 = vec2(0.0, -1.0);
2130
2131 assert!(right.angle_from_x_axis().get().approx_eq(&0.0));
2132 assert!(down.angle_from_x_axis().get().approx_eq(&FRAC_PI_2));
2133 assert!(up.angle_from_x_axis().get().approx_eq(&-FRAC_PI_2));
2134 }
2135
2136 #[test]
2137 pub fn test_angle_to() {
2138 use crate::approxeq::ApproxEq;
2139 use core::f32::consts::FRAC_PI_2;
2140
2141 let right: Vec2 = vec2(10.0, 0.0);
2142 let right2: Vec2 = vec2(1.0, 0.0);
2143 let up: Vec2 = vec2(0.0, -1.0);
2144 let up_left: Vec2 = vec2(-1.0, -1.0);
2145
2146 assert!(right.angle_to(right2).get().approx_eq(&0.0));
2147 assert!(right.angle_to(up).get().approx_eq(&-FRAC_PI_2));
2148 assert!(up.angle_to(right).get().approx_eq(&FRAC_PI_2));
2149 assert!(up_left
2150 .angle_to(up)
2151 .get()
2152 .approx_eq_eps(&(0.5 * FRAC_PI_2), &0.0005));
2153 }
2154
2155 #[test]
2156 pub fn test_with_max_length() {
2157 use crate::approxeq::ApproxEq;
2158
2159 let v1: Vec2 = vec2(0.5, 0.5);
2160 let v2: Vec2 = vec2(1.0, 0.0);
2161 let v3: Vec2 = vec2(0.1, 0.2);
2162 let v4: Vec2 = vec2(2.0, -2.0);
2163 let v5: Vec2 = vec2(1.0, 2.0);
2164 let v6: Vec2 = vec2(-1.0, 3.0);
2165
2166 assert_eq!(v1.with_max_length(1.0), v1);
2167 assert_eq!(v2.with_max_length(1.0), v2);
2168 assert_eq!(v3.with_max_length(1.0), v3);
2169 assert_eq!(v4.with_max_length(10.0), v4);
2170 assert_eq!(v5.with_max_length(10.0), v5);
2171 assert_eq!(v6.with_max_length(10.0), v6);
2172
2173 let v4_clamped = v4.with_max_length(1.0);
2174 assert!(v4_clamped.length().approx_eq(&1.0));
2175 assert!(v4_clamped.normalize().approx_eq(&v4.normalize()));
2176
2177 let v5_clamped = v5.with_max_length(1.5);
2178 assert!(v5_clamped.length().approx_eq(&1.5));
2179 assert!(v5_clamped.normalize().approx_eq(&v5.normalize()));
2180
2181 let v6_clamped = v6.with_max_length(2.5);
2182 assert!(v6_clamped.length().approx_eq(&2.5));
2183 assert!(v6_clamped.normalize().approx_eq(&v6.normalize()));
2184 }
2185
2186 #[test]
2187 pub fn test_project_onto_vector() {
2188 use crate::approxeq::ApproxEq;
2189
2190 let v1: Vec2 = vec2(1.0, 2.0);
2191 let x: Vec2 = vec2(1.0, 0.0);
2192 let y: Vec2 = vec2(0.0, 1.0);
2193
2194 assert!(v1.project_onto_vector(x).approx_eq(&vec2(1.0, 0.0)));
2195 assert!(v1.project_onto_vector(y).approx_eq(&vec2(0.0, 2.0)));
2196 assert!(v1.project_onto_vector(-x).approx_eq(&vec2(1.0, 0.0)));
2197 assert!(v1.project_onto_vector(x * 10.0).approx_eq(&vec2(1.0, 0.0)));
2198 assert!(v1.project_onto_vector(v1 * 2.0).approx_eq(&v1));
2199 assert!(v1.project_onto_vector(-v1).approx_eq(&v1));
2200 }
2201
2202 #[cfg(feature = "mint")]
2203 #[test]
2204 pub fn test_mint() {
2205 let v1 = Vec2::new(1.0, 3.0);
2206 let vm: mint::Vector2<_> = v1.into();
2207 let v2 = Vec2::from(vm);
2208
2209 assert_eq!(v1, v2);
2210 }
2211
2212 pub enum Mm {}
2213 pub enum Cm {}
2214
2215 pub type Vector2DMm<T> = super::Vector2D<T, Mm>;
2216 pub type Vector2DCm<T> = super::Vector2D<T, Cm>;
2217
2218 #[test]
2219 pub fn test_add() {
2220 let p1 = Vector2DMm::new(1.0, 2.0);
2221 let p2 = Vector2DMm::new(3.0, 4.0);
2222
2223 assert_eq!(p1 + p2, vec2(4.0, 6.0));
2224 assert_eq!(p1 + &p2, vec2(4.0, 6.0));
2225 }
2226
2227 #[test]
2228 pub fn test_sum() {
2229 let vecs = [
2230 Vector2DMm::new(1.0, 2.0),
2231 Vector2DMm::new(3.0, 4.0),
2232 Vector2DMm::new(5.0, 6.0)
2233 ];
2234 let sum = Vector2DMm::new(9.0, 12.0);
2235 assert_eq!(vecs.iter().sum::<Vector2DMm<_>>(), sum);
2236 }
2237
2238 #[test]
2239 pub fn test_add_assign() {
2240 let mut p1 = Vector2DMm::new(1.0, 2.0);
2241 p1 += vec2(3.0, 4.0);
2242
2243 assert_eq!(p1, vec2(4.0, 6.0));
2244 }
2245
2246 #[test]
2247 pub fn test_tpyed_scalar_mul() {
2248 let p1 = Vector2DMm::new(1.0, 2.0);
2249 let cm_per_mm = Scale::<f32, Mm, Cm>::new(0.1);
2250
2251 let result: Vector2DCm<f32> = p1 * cm_per_mm;
2252
2253 assert_eq!(result, vec2(0.1, 0.2));
2254 }
2255
2256 #[test]
2257 pub fn test_swizzling() {
2258 let p: default::Vector2D<i32> = vec2(1, 2);
2259 assert_eq!(p.yx(), vec2(2, 1));
2260 }
2261
2262 #[test]
2263 pub fn test_reflect() {
2264 use crate::approxeq::ApproxEq;
2265 let a: Vec2 = vec2(1.0, 3.0);
2266 let n1: Vec2 = vec2(0.0, -1.0);
2267 let n2: Vec2 = vec2(1.0, -1.0).normalize();
2268
2269 assert!(a.reflect(n1).approx_eq(&vec2(1.0, -3.0)));
2270 assert!(a.reflect(n2).approx_eq(&vec2(3.0, 1.0)));
2271 }
2272}
2273
2274#[cfg(test)]
2275mod vector3d {
2276 use crate::scale::Scale;
2277 use crate::{default, vec2, vec3};
2278 #[cfg(feature = "mint")]
2279 use mint;
2280
2281 type Vec3 = default::Vector3D<f32>;
2282
2283 #[test]
2284 pub fn test_add() {
2285 let p1 = Vec3::new(1.0, 2.0, 3.0);
2286 let p2 = Vec3::new(4.0, 5.0, 6.0);
2287
2288 assert_eq!(p1 + p2, vec3(5.0, 7.0, 9.0));
2289 assert_eq!(p1 + &p2, vec3(5.0, 7.0, 9.0));
2290 }
2291
2292 #[test]
2293 pub fn test_sum() {
2294 let vecs = [
2295 Vec3::new(1.0, 2.0, 3.0),
2296 Vec3::new(4.0, 5.0, 6.0),
2297 Vec3::new(7.0, 8.0, 9.0)
2298 ];
2299 let sum = Vec3::new(12.0, 15.0, 18.0);
2300 assert_eq!(vecs.iter().sum::<Vec3>(), sum);
2301 }
2302
2303 #[test]
2304 pub fn test_dot() {
2305 let p1: Vec3 = vec3(7.0, 21.0, 32.0);
2306 let p2: Vec3 = vec3(43.0, 5.0, 16.0);
2307 assert_eq!(p1.dot(p2), 918.0);
2308 }
2309
2310 #[test]
2311 pub fn test_cross() {
2312 let p1: Vec3 = vec3(4.0, 7.0, 9.0);
2313 let p2: Vec3 = vec3(13.0, 8.0, 3.0);
2314 let p3 = p1.cross(p2);
2315 assert_eq!(p3, vec3(-51.0, 105.0, -59.0));
2316 }
2317
2318 #[test]
2319 pub fn test_normalize() {
2320 use std::f32;
2321
2322 let p0: Vec3 = Vec3::zero();
2323 let p1: Vec3 = vec3(0.0, -6.0, 0.0);
2324 let p2: Vec3 = vec3(1.0, 2.0, -2.0);
2325 assert!(
2326 p0.normalize().x.is_nan() && p0.normalize().y.is_nan() && p0.normalize().z.is_nan()
2327 );
2328 assert_eq!(p1.normalize(), vec3(0.0, -1.0, 0.0));
2329 assert_eq!(p2.normalize(), vec3(1.0 / 3.0, 2.0 / 3.0, -2.0 / 3.0));
2330
2331 let p3: Vec3 = vec3(::std::f32::MAX, ::std::f32::MAX, 0.0);
2332 assert_ne!(
2333 p3.normalize(),
2334 vec3(1.0 / 2.0f32.sqrt(), 1.0 / 2.0f32.sqrt(), 0.0)
2335 );
2336 assert_eq!(
2337 p3.robust_normalize(),
2338 vec3(1.0 / 2.0f32.sqrt(), 1.0 / 2.0f32.sqrt(), 0.0)
2339 );
2340
2341 let p4: Vec3 = Vec3::zero();
2342 assert!(p4.try_normalize().is_none());
2343 let p5: Vec3 = Vec3::new(f32::MIN_POSITIVE, f32::MIN_POSITIVE, f32::MIN_POSITIVE);
2344 assert!(p5.try_normalize().is_none());
2345
2346 let p6: Vec3 = vec3(4.0, 0.0, 3.0);
2347 let p7: Vec3 = vec3(3.0, -4.0, 0.0);
2348 assert_eq!(p6.try_normalize().unwrap(), vec3(0.8, 0.0, 0.6));
2349 assert_eq!(p7.try_normalize().unwrap(), vec3(0.6, -0.8, 0.0));
2350 }
2351
2352 #[test]
2353 pub fn test_min() {
2354 let p1: Vec3 = vec3(1.0, 3.0, 5.0);
2355 let p2: Vec3 = vec3(2.0, 2.0, -1.0);
2356
2357 let result = p1.min(p2);
2358
2359 assert_eq!(result, vec3(1.0, 2.0, -1.0));
2360 }
2361
2362 #[test]
2363 pub fn test_max() {
2364 let p1: Vec3 = vec3(1.0, 3.0, 5.0);
2365 let p2: Vec3 = vec3(2.0, 2.0, -1.0);
2366
2367 let result = p1.max(p2);
2368
2369 assert_eq!(result, vec3(2.0, 3.0, 5.0));
2370 }
2371
2372 #[test]
2373 pub fn test_clamp() {
2374 let p1: Vec3 = vec3(1.0, -1.0, 5.0);
2375 let p2: Vec3 = vec3(2.0, 5.0, 10.0);
2376 let p3: Vec3 = vec3(-1.0, 2.0, 20.0);
2377
2378 let result = p3.clamp(p1, p2);
2379
2380 assert_eq!(result, vec3(1.0, 2.0, 10.0));
2381 }
2382
2383 #[test]
2384 pub fn test_typed_scalar_mul() {
2385 enum Mm {}
2386 enum Cm {}
2387
2388 let p1 = super::Vector3D::<f32, Mm>::new(1.0, 2.0, 3.0);
2389 let cm_per_mm = Scale::<f32, Mm, Cm>::new(0.1);
2390
2391 let result: super::Vector3D<f32, Cm> = p1 * cm_per_mm;
2392
2393 assert_eq!(result, vec3(0.1, 0.2, 0.3));
2394 }
2395
2396 #[test]
2397 pub fn test_swizzling() {
2398 let p: Vec3 = vec3(1.0, 2.0, 3.0);
2399 assert_eq!(p.xy(), vec2(1.0, 2.0));
2400 assert_eq!(p.xz(), vec2(1.0, 3.0));
2401 assert_eq!(p.yz(), vec2(2.0, 3.0));
2402 }
2403
2404 #[cfg(feature = "mint")]
2405 #[test]
2406 pub fn test_mint() {
2407 let v1 = Vec3::new(1.0, 3.0, 5.0);
2408 let vm: mint::Vector3<_> = v1.into();
2409 let v2 = Vec3::from(vm);
2410
2411 assert_eq!(v1, v2);
2412 }
2413
2414 #[test]
2415 pub fn test_reflect() {
2416 use crate::approxeq::ApproxEq;
2417 let a: Vec3 = vec3(1.0, 3.0, 2.0);
2418 let n1: Vec3 = vec3(0.0, -1.0, 0.0);
2419 let n2: Vec3 = vec3(0.0, 1.0, 1.0).normalize();
2420
2421 assert!(a.reflect(n1).approx_eq(&vec3(1.0, -3.0, 2.0)));
2422 assert!(a.reflect(n2).approx_eq(&vec3(1.0, -2.0, -3.0)));
2423 }
2424
2425 #[test]
2426 pub fn test_angle_to() {
2427 use crate::approxeq::ApproxEq;
2428 use core::f32::consts::FRAC_PI_2;
2429
2430 let right: Vec3 = vec3(10.0, 0.0, 0.0);
2431 let right2: Vec3 = vec3(1.0, 0.0, 0.0);
2432 let up: Vec3 = vec3(0.0, -1.0, 0.0);
2433 let up_left: Vec3 = vec3(-1.0, -1.0, 0.0);
2434
2435 assert!(right.angle_to(right2).get().approx_eq(&0.0));
2436 assert!(right.angle_to(up).get().approx_eq(&FRAC_PI_2));
2437 assert!(up.angle_to(right).get().approx_eq(&FRAC_PI_2));
2438 assert!(up_left
2439 .angle_to(up)
2440 .get()
2441 .approx_eq_eps(&(0.5 * FRAC_PI_2), &0.0005));
2442 }
2443
2444 #[test]
2445 pub fn test_with_max_length() {
2446 use crate::approxeq::ApproxEq;
2447
2448 let v1: Vec3 = vec3(0.5, 0.5, 0.0);
2449 let v2: Vec3 = vec3(1.0, 0.0, 0.0);
2450 let v3: Vec3 = vec3(0.1, 0.2, 0.3);
2451 let v4: Vec3 = vec3(2.0, -2.0, 2.0);
2452 let v5: Vec3 = vec3(1.0, 2.0, -3.0);
2453 let v6: Vec3 = vec3(-1.0, 3.0, 2.0);
2454
2455 assert_eq!(v1.with_max_length(1.0), v1);
2456 assert_eq!(v2.with_max_length(1.0), v2);
2457 assert_eq!(v3.with_max_length(1.0), v3);
2458 assert_eq!(v4.with_max_length(10.0), v4);
2459 assert_eq!(v5.with_max_length(10.0), v5);
2460 assert_eq!(v6.with_max_length(10.0), v6);
2461
2462 let v4_clamped = v4.with_max_length(1.0);
2463 assert!(v4_clamped.length().approx_eq(&1.0));
2464 assert!(v4_clamped.normalize().approx_eq(&v4.normalize()));
2465
2466 let v5_clamped = v5.with_max_length(1.5);
2467 assert!(v5_clamped.length().approx_eq(&1.5));
2468 assert!(v5_clamped.normalize().approx_eq(&v5.normalize()));
2469
2470 let v6_clamped = v6.with_max_length(2.5);
2471 assert!(v6_clamped.length().approx_eq(&2.5));
2472 assert!(v6_clamped.normalize().approx_eq(&v6.normalize()));
2473 }
2474
2475 #[test]
2476 pub fn test_project_onto_vector() {
2477 use crate::approxeq::ApproxEq;
2478
2479 let v1: Vec3 = vec3(1.0, 2.0, 3.0);
2480 let x: Vec3 = vec3(1.0, 0.0, 0.0);
2481 let y: Vec3 = vec3(0.0, 1.0, 0.0);
2482 let z: Vec3 = vec3(0.0, 0.0, 1.0);
2483
2484 assert!(v1.project_onto_vector(x).approx_eq(&vec3(1.0, 0.0, 0.0)));
2485 assert!(v1.project_onto_vector(y).approx_eq(&vec3(0.0, 2.0, 0.0)));
2486 assert!(v1.project_onto_vector(z).approx_eq(&vec3(0.0, 0.0, 3.0)));
2487 assert!(v1.project_onto_vector(-x).approx_eq(&vec3(1.0, 0.0, 0.0)));
2488 assert!(v1
2489 .project_onto_vector(x * 10.0)
2490 .approx_eq(&vec3(1.0, 0.0, 0.0)));
2491 assert!(v1.project_onto_vector(v1 * 2.0).approx_eq(&v1));
2492 assert!(v1.project_onto_vector(-v1).approx_eq(&v1));
2493 }
2494}
2495
2496#[cfg(test)]
2497mod bool_vector {
2498 use super::*;
2499 use crate::default;
2500 type Vec2 = default::Vector2D<f32>;
2501 type Vec3 = default::Vector3D<f32>;
2502
2503 #[test]
2504 fn test_bvec2() {
2505 assert_eq!(
2506 Vec2::new(1.0, 2.0).greater_than(Vec2::new(2.0, 1.0)),
2507 bvec2(false, true),
2508 );
2509
2510 assert_eq!(
2511 Vec2::new(1.0, 2.0).lower_than(Vec2::new(2.0, 1.0)),
2512 bvec2(true, false),
2513 );
2514
2515 assert_eq!(
2516 Vec2::new(1.0, 2.0).equal(Vec2::new(1.0, 3.0)),
2517 bvec2(true, false),
2518 );
2519
2520 assert_eq!(
2521 Vec2::new(1.0, 2.0).not_equal(Vec2::new(1.0, 3.0)),
2522 bvec2(false, true),
2523 );
2524
2525 assert!(bvec2(true, true).any());
2526 assert!(bvec2(false, true).any());
2527 assert!(bvec2(true, false).any());
2528 assert!(!bvec2(false, false).any());
2529 assert!(bvec2(false, false).none());
2530 assert!(bvec2(true, true).all());
2531 assert!(!bvec2(false, true).all());
2532 assert!(!bvec2(true, false).all());
2533 assert!(!bvec2(false, false).all());
2534
2535 assert_eq!(bvec2(true, false).not(), bvec2(false, true));
2536 assert_eq!(
2537 bvec2(true, false).and(bvec2(true, true)),
2538 bvec2(true, false)
2539 );
2540 assert_eq!(bvec2(true, false).or(bvec2(true, true)), bvec2(true, true));
2541
2542 assert_eq!(
2543 bvec2(true, false).select_vector(Vec2::new(1.0, 2.0), Vec2::new(3.0, 4.0)),
2544 Vec2::new(1.0, 4.0),
2545 );
2546 }
2547
2548 #[test]
2549 fn test_bvec3() {
2550 assert_eq!(
2551 Vec3::new(1.0, 2.0, 3.0).greater_than(Vec3::new(3.0, 2.0, 1.0)),
2552 bvec3(false, false, true),
2553 );
2554
2555 assert_eq!(
2556 Vec3::new(1.0, 2.0, 3.0).lower_than(Vec3::new(3.0, 2.0, 1.0)),
2557 bvec3(true, false, false),
2558 );
2559
2560 assert_eq!(
2561 Vec3::new(1.0, 2.0, 3.0).equal(Vec3::new(3.0, 2.0, 1.0)),
2562 bvec3(false, true, false),
2563 );
2564
2565 assert_eq!(
2566 Vec3::new(1.0, 2.0, 3.0).not_equal(Vec3::new(3.0, 2.0, 1.0)),
2567 bvec3(true, false, true),
2568 );
2569
2570 assert!(bvec3(true, true, false).any());
2571 assert!(bvec3(false, true, false).any());
2572 assert!(bvec3(true, false, false).any());
2573 assert!(!bvec3(false, false, false).any());
2574 assert!(bvec3(false, false, false).none());
2575 assert!(bvec3(true, true, true).all());
2576 assert!(!bvec3(false, true, false).all());
2577 assert!(!bvec3(true, false, false).all());
2578 assert!(!bvec3(false, false, false).all());
2579
2580 assert_eq!(bvec3(true, false, true).not(), bvec3(false, true, false));
2581 assert_eq!(
2582 bvec3(true, false, true).and(bvec3(true, true, false)),
2583 bvec3(true, false, false)
2584 );
2585 assert_eq!(
2586 bvec3(true, false, false).or(bvec3(true, true, false)),
2587 bvec3(true, true, false)
2588 );
2589
2590 assert_eq!(
2591 bvec3(true, false, true)
2592 .select_vector(Vec3::new(1.0, 2.0, 3.0), Vec3::new(4.0, 5.0, 6.0)),
2593 Vec3::new(1.0, 5.0, 3.0),
2594 );
2595 }
2596}
2597