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