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