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