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