Skip to main content

euclid/
vector.rs

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