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 crate::approxeq::ApproxEq;
12 use crate::approxord::{max, min};
13 use crate::length::Length;
14 use crate::num::*;
15 use crate::scale::Scale;
16 use crate::size::{Size2D, Size3D};
17 use crate::vector::{vec2, vec3, Vector2D, Vector3D};
18 use core::cmp::{Eq, PartialEq};
19 use core::fmt;
20 use core::hash::Hash;
21 use core::marker::PhantomData;
22 use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
23 #[cfg(feature = "mint")]
24 use mint;
25 use num_traits::{Float, NumCast};
26 #[cfg(feature = "serde")]
27 use serde;
28 
29 /// A 2d Point tagged with a unit.
30 #[repr(C)]
31 pub struct Point2D<T, U> {
32     pub x: T,
33     pub y: T,
34     #[doc(hidden)]
35     pub _unit: PhantomData<U>,
36 }
37 
38 impl<T: Copy, U> Copy for Point2D<T, U> {}
39 
40 impl<T: Clone, U> Clone for Point2D<T, U> {
clone(&self) -> Self41     fn clone(&self) -> Self {
42         Point2D {
43             x: self.x.clone(),
44             y: self.y.clone(),
45             _unit: PhantomData,
46         }
47     }
48 }
49 
50 #[cfg(feature = "serde")]
51 impl<'de, T, U> serde::Deserialize<'de> for Point2D<T, U>
52 where
53     T: serde::Deserialize<'de>,
54 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de>,55     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
56     where
57         D: serde::Deserializer<'de>,
58     {
59         let (x, y) = serde::Deserialize::deserialize(deserializer)?;
60         Ok(Point2D {
61             x,
62             y,
63             _unit: PhantomData,
64         })
65     }
66 }
67 
68 #[cfg(feature = "serde")]
69 impl<T, U> serde::Serialize for Point2D<T, U>
70 where
71     T: serde::Serialize,
72 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer,73     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
74     where
75         S: serde::Serializer,
76     {
77         (&self.x, &self.y).serialize(serializer)
78     }
79 }
80 
81 #[cfg(feature = "arbitrary")]
82 impl<'a, T, U> arbitrary::Arbitrary<'a> for Point2D<T, U>
83 where
84     T: arbitrary::Arbitrary<'a>,
85 {
arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self>86     fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self>
87     {
88         let (x, y) = arbitrary::Arbitrary::arbitrary(u)?;
89         Ok(Point2D {
90             x,
91             y,
92             _unit: PhantomData,
93         })
94     }
95 }
96 impl<T, U> Eq for Point2D<T, U> where T: Eq {}
97 
98 impl<T, U> PartialEq for Point2D<T, U>
99 where
100     T: PartialEq,
101 {
eq(&self, other: &Self) -> bool102     fn eq(&self, other: &Self) -> bool {
103         self.x == other.x && self.y == other.y
104     }
105 }
106 
107 impl<T, U> Hash for Point2D<T, U>
108 where
109     T: Hash,
110 {
hash<H: core::hash::Hasher>(&self, h: &mut H)111     fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
112         self.x.hash(h);
113         self.y.hash(h);
114     }
115 }
116 
117 mint_vec!(Point2D[x, y] = Point2);
118 
119 impl<T: fmt::Debug, U> fmt::Debug for Point2D<T, U> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result120     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121         f.debug_tuple("").field(&self.x).field(&self.y).finish()
122     }
123 }
124 
125 impl<T: Default, U> Default for Point2D<T, U> {
default() -> Self126     fn default() -> Self {
127         Point2D::new(Default::default(), Default::default())
128     }
129 }
130 
131 impl<T, U> Point2D<T, U> {
132     /// Constructor, setting all components to zero.
133     #[inline]
origin() -> Self where T: Zero,134     pub fn origin() -> Self
135     where
136         T: Zero,
137     {
138         point2(Zero::zero(), Zero::zero())
139     }
140 
141     /// The same as [`origin()`](#method.origin).
142     #[inline]
zero() -> Self where T: Zero,143     pub fn zero() -> Self
144     where
145         T: Zero,
146     {
147         Self::origin()
148     }
149 
150     /// Constructor taking scalar values directly.
151     #[inline]
new(x: T, y: T) -> Self152     pub const fn new(x: T, y: T) -> Self {
153         Point2D {
154             x,
155             y,
156             _unit: PhantomData,
157         }
158     }
159 
160     /// Constructor taking properly Lengths instead of scalar values.
161     #[inline]
from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self162     pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self {
163         point2(x.0, y.0)
164     }
165 
166     /// Constructor setting all components to the same value.
167     #[inline]
splat(v: T) -> Self where T: Clone,168     pub fn splat(v: T) -> Self
169     where
170         T: Clone,
171     {
172         Point2D {
173             x: v.clone(),
174             y: v,
175             _unit: PhantomData,
176         }
177     }
178 
179     /// Tag a unitless value with units.
180     #[inline]
from_untyped(p: Point2D<T, UnknownUnit>) -> Self181     pub fn from_untyped(p: Point2D<T, UnknownUnit>) -> Self {
182         point2(p.x, p.y)
183     }
184 }
185 
186 impl<T: Copy, U> Point2D<T, U> {
187     /// Create a 3d point from this one, using the specified z value.
188     #[inline]
extend(self, z: T) -> Point3D<T, U>189     pub fn extend(self, z: T) -> Point3D<T, U> {
190         point3(self.x, self.y, z)
191     }
192 
193     /// Cast this point into a vector.
194     ///
195     /// Equivalent to subtracting the origin from this point.
196     #[inline]
to_vector(self) -> Vector2D<T, U>197     pub fn to_vector(self) -> Vector2D<T, U> {
198         Vector2D {
199             x: self.x,
200             y: self.y,
201             _unit: PhantomData,
202         }
203     }
204 
205     /// Swap x and y.
206     ///
207     /// # Example
208     ///
209     /// ```rust
210     /// # use euclid::{Point2D, point2};
211     /// enum Mm {}
212     ///
213     /// let point: Point2D<_, Mm> = point2(1, -8);
214     ///
215     /// assert_eq!(point.yx(), point2(-8, 1));
216     /// ```
217     #[inline]
yx(self) -> Self218     pub fn yx(self) -> Self {
219         point2(self.y, self.x)
220     }
221 
222     /// Drop the units, preserving only the numeric value.
223     ///
224     /// # Example
225     ///
226     /// ```rust
227     /// # use euclid::{Point2D, point2};
228     /// enum Mm {}
229     ///
230     /// let point: Point2D<_, Mm> = point2(1, -8);
231     ///
232     /// assert_eq!(point.x, point.to_untyped().x);
233     /// assert_eq!(point.y, point.to_untyped().y);
234     /// ```
235     #[inline]
to_untyped(self) -> Point2D<T, UnknownUnit>236     pub fn to_untyped(self) -> Point2D<T, UnknownUnit> {
237         point2(self.x, self.y)
238     }
239 
240     /// Cast the unit, preserving the numeric value.
241     ///
242     /// # Example
243     ///
244     /// ```rust
245     /// # use euclid::{Point2D, point2};
246     /// enum Mm {}
247     /// enum Cm {}
248     ///
249     /// let point: Point2D<_, Mm> = point2(1, -8);
250     ///
251     /// assert_eq!(point.x, point.cast_unit::<Cm>().x);
252     /// assert_eq!(point.y, point.cast_unit::<Cm>().y);
253     /// ```
254     #[inline]
cast_unit<V>(self) -> Point2D<T, V>255     pub fn cast_unit<V>(self) -> Point2D<T, V> {
256         point2(self.x, self.y)
257     }
258 
259     /// Cast into an array with x and y.
260     ///
261     /// # Example
262     ///
263     /// ```rust
264     /// # use euclid::{Point2D, point2};
265     /// enum Mm {}
266     ///
267     /// let point: Point2D<_, Mm> = point2(1, -8);
268     ///
269     /// assert_eq!(point.to_array(), [1, -8]);
270     /// ```
271     #[inline]
to_array(self) -> [T; 2]272     pub fn to_array(self) -> [T; 2] {
273         [self.x, self.y]
274     }
275 
276     /// Cast into a tuple with x and y.
277     ///
278     /// # Example
279     ///
280     /// ```rust
281     /// # use euclid::{Point2D, point2};
282     /// enum Mm {}
283     ///
284     /// let point: Point2D<_, Mm> = point2(1, -8);
285     ///
286     /// assert_eq!(point.to_tuple(), (1, -8));
287     /// ```
288     #[inline]
to_tuple(self) -> (T, T)289     pub fn to_tuple(self) -> (T, T) {
290         (self.x, self.y)
291     }
292 
293     /// Convert into a 3d point with z-coordinate equals to zero.
294     #[inline]
to_3d(self) -> Point3D<T, U> where T: Zero,295     pub fn to_3d(self) -> Point3D<T, U>
296     where
297         T: Zero,
298     {
299         point3(self.x, self.y, Zero::zero())
300     }
301 
302     /// Rounds each component to the nearest integer value.
303     ///
304     /// This behavior is preserved for negative values (unlike the basic cast).
305     ///
306     /// ```rust
307     /// # use euclid::point2;
308     /// enum Mm {}
309     ///
310     /// assert_eq!(point2::<_, Mm>(-0.1, -0.8).round(), point2::<_, Mm>(0.0, -1.0))
311     /// ```
312     #[inline]
313     #[must_use]
round(self) -> Self where T: Round,314     pub fn round(self) -> Self
315     where
316         T: Round,
317     {
318         point2(self.x.round(), self.y.round())
319     }
320 
321     /// Rounds each component to the smallest integer equal or greater than the original value.
322     ///
323     /// This behavior is preserved for negative values (unlike the basic cast).
324     ///
325     /// ```rust
326     /// # use euclid::point2;
327     /// enum Mm {}
328     ///
329     /// assert_eq!(point2::<_, Mm>(-0.1, -0.8).ceil(), point2::<_, Mm>(0.0, 0.0))
330     /// ```
331     #[inline]
332     #[must_use]
ceil(self) -> Self where T: Ceil,333     pub fn ceil(self) -> Self
334     where
335         T: Ceil,
336     {
337         point2(self.x.ceil(), self.y.ceil())
338     }
339 
340     /// Rounds each component to the biggest integer equal or lower than the original value.
341     ///
342     /// This behavior is preserved for negative values (unlike the basic cast).
343     ///
344     /// ```rust
345     /// # use euclid::point2;
346     /// enum Mm {}
347     ///
348     /// assert_eq!(point2::<_, Mm>(-0.1, -0.8).floor(), point2::<_, Mm>(-1.0, -1.0))
349     /// ```
350     #[inline]
351     #[must_use]
floor(self) -> Self where T: Floor,352     pub fn floor(self) -> Self
353     where
354         T: Floor,
355     {
356         point2(self.x.floor(), self.y.floor())
357     }
358 
359     /// Linearly interpolate between this point and another point.
360     ///
361     /// # Example
362     ///
363     /// ```rust
364     /// use euclid::point2;
365     /// use euclid::default::Point2D;
366     ///
367     /// let from: Point2D<_> = point2(0.0, 10.0);
368     /// let to:  Point2D<_> = point2(8.0, -4.0);
369     ///
370     /// assert_eq!(from.lerp(to, -1.0), point2(-8.0,  24.0));
371     /// assert_eq!(from.lerp(to,  0.0), point2( 0.0,  10.0));
372     /// assert_eq!(from.lerp(to,  0.5), point2( 4.0,   3.0));
373     /// assert_eq!(from.lerp(to,  1.0), point2( 8.0,  -4.0));
374     /// assert_eq!(from.lerp(to,  2.0), point2(16.0, -18.0));
375     /// ```
376     #[inline]
lerp(self, other: Self, t: T) -> Self where T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,377     pub fn lerp(self, other: Self, t: T) -> Self
378     where
379         T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
380     {
381         let one_t = T::one() - t;
382         point2(one_t * self.x + t * other.x, one_t * self.y + t * other.y)
383     }
384 }
385 
386 impl<T: PartialOrd, U> Point2D<T, U> {
387     #[inline]
min(self, other: Self) -> Self388     pub fn min(self, other: Self) -> Self {
389         point2(min(self.x, other.x), min(self.y, other.y))
390     }
391 
392     #[inline]
max(self, other: Self) -> Self393     pub fn max(self, other: Self) -> Self {
394         point2(max(self.x, other.x), max(self.y, other.y))
395     }
396 
397     /// Returns the point each component of which clamped by corresponding
398     /// components of `start` and `end`.
399     ///
400     /// Shortcut for `self.max(start).min(end)`.
401     #[inline]
clamp(self, start: Self, end: Self) -> Self where T: Copy,402     pub fn clamp(self, start: Self, end: Self) -> Self
403     where
404         T: Copy,
405     {
406         self.max(start).min(end)
407     }
408 }
409 
410 impl<T: NumCast + Copy, U> Point2D<T, U> {
411     /// Cast from one numeric representation to another, preserving the units.
412     ///
413     /// When casting from floating point to integer coordinates, the decimals are truncated
414     /// as one would expect from a simple cast, but this behavior does not always make sense
415     /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
416     #[inline]
cast<NewT: NumCast>(self) -> Point2D<NewT, U>417     pub fn cast<NewT: NumCast>(self) -> Point2D<NewT, U> {
418         self.try_cast().unwrap()
419     }
420 
421     /// Fallible cast from one numeric representation to another, preserving the units.
422     ///
423     /// When casting from floating point to integer coordinates, the decimals are truncated
424     /// as one would expect from a simple cast, but this behavior does not always make sense
425     /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
try_cast<NewT: NumCast>(self) -> Option<Point2D<NewT, U>>426     pub fn try_cast<NewT: NumCast>(self) -> Option<Point2D<NewT, U>> {
427         match (NumCast::from(self.x), NumCast::from(self.y)) {
428             (Some(x), Some(y)) => Some(point2(x, y)),
429             _ => None,
430         }
431     }
432 
433     // Convenience functions for common casts
434 
435     /// Cast into an `f32` point.
436     #[inline]
to_f32(self) -> Point2D<f32, U>437     pub fn to_f32(self) -> Point2D<f32, U> {
438         self.cast()
439     }
440 
441     /// Cast into an `f64` point.
442     #[inline]
to_f64(self) -> Point2D<f64, U>443     pub fn to_f64(self) -> Point2D<f64, U> {
444         self.cast()
445     }
446 
447     /// Cast into an `usize` point, truncating decimals if any.
448     ///
449     /// When casting from floating point points, it is worth considering whether
450     /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
451     /// the desired conversion behavior.
452     #[inline]
to_usize(self) -> Point2D<usize, U>453     pub fn to_usize(self) -> Point2D<usize, U> {
454         self.cast()
455     }
456 
457     /// Cast into an `u32` point, truncating decimals if any.
458     ///
459     /// When casting from floating point points, it is worth considering whether
460     /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
461     /// the desired conversion behavior.
462     #[inline]
to_u32(self) -> Point2D<u32, U>463     pub fn to_u32(self) -> Point2D<u32, U> {
464         self.cast()
465     }
466 
467     /// Cast into an i32 point, truncating decimals if any.
468     ///
469     /// When casting from floating point points, it is worth considering whether
470     /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
471     /// the desired conversion behavior.
472     #[inline]
to_i32(self) -> Point2D<i32, U>473     pub fn to_i32(self) -> Point2D<i32, U> {
474         self.cast()
475     }
476 
477     /// Cast into an i64 point, truncating decimals if any.
478     ///
479     /// When casting from floating point points, it is worth considering whether
480     /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
481     /// the desired conversion behavior.
482     #[inline]
to_i64(self) -> Point2D<i64, U>483     pub fn to_i64(self) -> Point2D<i64, U> {
484         self.cast()
485     }
486 }
487 
488 impl<T: Float, U> Point2D<T, U> {
489     /// Returns true if all members are finite.
490     #[inline]
is_finite(self) -> bool491     pub fn is_finite(self) -> bool {
492         self.x.is_finite() && self.y.is_finite()
493     }
494 }
495 
496 impl<T: Copy + Add<T, Output = T>, U> Point2D<T, U> {
497     #[inline]
add_size(self, other: &Size2D<T, U>) -> Self498     pub fn add_size(self, other: &Size2D<T, U>) -> Self {
499         point2(self.x + other.width, self.y + other.height)
500     }
501 }
502 
503 impl<T: Float + Sub<T, Output = T>, U> Point2D<T, U> {
504     #[inline]
distance_to(self, other: Self) -> T505     pub fn distance_to(self, other: Self) -> T {
506         (self - other).length()
507     }
508 }
509 
510 impl<T: Neg, U> Neg for Point2D<T, U> {
511     type Output = Point2D<T::Output, U>;
512 
513     #[inline]
neg(self) -> Self::Output514     fn neg(self) -> Self::Output {
515         point2(-self.x, -self.y)
516     }
517 }
518 
519 impl<T: Add, U> Add<Size2D<T, U>> for Point2D<T, U> {
520     type Output = Point2D<T::Output, U>;
521 
522     #[inline]
add(self, other: Size2D<T, U>) -> Self::Output523     fn add(self, other: Size2D<T, U>) -> Self::Output {
524         point2(self.x + other.width, self.y + other.height)
525     }
526 }
527 
528 impl<T: AddAssign, U> AddAssign<Size2D<T, U>> for Point2D<T, U> {
529     #[inline]
add_assign(&mut self, other: Size2D<T, U>)530     fn add_assign(&mut self, other: Size2D<T, U>) {
531         self.x += other.width;
532         self.y += other.height;
533     }
534 }
535 
536 impl<T: Add, U> Add<Vector2D<T, U>> for Point2D<T, U> {
537     type Output = Point2D<T::Output, U>;
538 
539     #[inline]
add(self, other: Vector2D<T, U>) -> Self::Output540     fn add(self, other: Vector2D<T, U>) -> Self::Output {
541         point2(self.x + other.x, self.y + other.y)
542     }
543 }
544 
545 impl<T: Copy + Add<T, Output = T>, U> AddAssign<Vector2D<T, U>> for Point2D<T, U> {
546     #[inline]
add_assign(&mut self, other: Vector2D<T, U>)547     fn add_assign(&mut self, other: Vector2D<T, U>) {
548         *self = *self + other
549     }
550 }
551 
552 impl<T: Sub, U> Sub for Point2D<T, U> {
553     type Output = Vector2D<T::Output, U>;
554 
555     #[inline]
sub(self, other: Self) -> Self::Output556     fn sub(self, other: Self) -> Self::Output {
557         vec2(self.x - other.x, self.y - other.y)
558     }
559 }
560 
561 impl<T: Sub, U> Sub<Size2D<T, U>> for Point2D<T, U> {
562     type Output = Point2D<T::Output, U>;
563 
564     #[inline]
sub(self, other: Size2D<T, U>) -> Self::Output565     fn sub(self, other: Size2D<T, U>) -> Self::Output {
566         point2(self.x - other.width, self.y - other.height)
567     }
568 }
569 
570 impl<T: SubAssign, U> SubAssign<Size2D<T, U>> for Point2D<T, U> {
571     #[inline]
sub_assign(&mut self, other: Size2D<T, U>)572     fn sub_assign(&mut self, other: Size2D<T, U>) {
573         self.x -= other.width;
574         self.y -= other.height;
575     }
576 }
577 
578 impl<T: Sub, U> Sub<Vector2D<T, U>> for Point2D<T, U> {
579     type Output = Point2D<T::Output, U>;
580 
581     #[inline]
sub(self, other: Vector2D<T, U>) -> Self::Output582     fn sub(self, other: Vector2D<T, U>) -> Self::Output {
583         point2(self.x - other.x, self.y - other.y)
584     }
585 }
586 
587 impl<T: Copy + Sub<T, Output = T>, U> SubAssign<Vector2D<T, U>> for Point2D<T, U> {
588     #[inline]
sub_assign(&mut self, other: Vector2D<T, U>)589     fn sub_assign(&mut self, other: Vector2D<T, U>) {
590         *self = *self - other
591     }
592 }
593 
594 impl<T: Copy + Mul, U> Mul<T> for Point2D<T, U> {
595     type Output = Point2D<T::Output, U>;
596 
597     #[inline]
mul(self, scale: T) -> Self::Output598     fn mul(self, scale: T) -> Self::Output {
599         point2(self.x * scale, self.y * scale)
600     }
601 }
602 
603 impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Point2D<T, U> {
604     #[inline]
mul_assign(&mut self, scale: T)605     fn mul_assign(&mut self, scale: T) {
606         *self = *self * scale
607     }
608 }
609 
610 impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Point2D<T, U1> {
611     type Output = Point2D<T::Output, U2>;
612 
613     #[inline]
mul(self, scale: Scale<T, U1, U2>) -> Self::Output614     fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
615         point2(self.x * scale.0, self.y * scale.0)
616     }
617 }
618 
619 impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Point2D<T, U> {
620     #[inline]
mul_assign(&mut self, scale: Scale<T, U, U>)621     fn mul_assign(&mut self, scale: Scale<T, U, U>) {
622         self.x *= scale.0;
623         self.y *= scale.0;
624     }
625 }
626 
627 impl<T: Copy + Div, U> Div<T> for Point2D<T, U> {
628     type Output = Point2D<T::Output, U>;
629 
630     #[inline]
div(self, scale: T) -> Self::Output631     fn div(self, scale: T) -> Self::Output {
632         point2(self.x / scale, self.y / scale)
633     }
634 }
635 
636 impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Point2D<T, U> {
637     #[inline]
div_assign(&mut self, scale: T)638     fn div_assign(&mut self, scale: T) {
639         *self = *self / scale
640     }
641 }
642 
643 impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Point2D<T, U2> {
644     type Output = Point2D<T::Output, U1>;
645 
646     #[inline]
div(self, scale: Scale<T, U1, U2>) -> Self::Output647     fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
648         point2(self.x / scale.0, self.y / scale.0)
649     }
650 }
651 
652 impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Point2D<T, U> {
653     #[inline]
div_assign(&mut self, scale: Scale<T, U, U>)654     fn div_assign(&mut self, scale: Scale<T, U, U>) {
655         self.x /= scale.0;
656         self.y /= scale.0;
657     }
658 }
659 
660 impl<T: Zero, U> Zero for Point2D<T, U> {
661     #[inline]
zero() -> Self662     fn zero() -> Self {
663         Self::origin()
664     }
665 }
666 
667 impl<T: Round, U> Round for Point2D<T, U> {
668     /// See [Point2D::round()](#method.round)
669     #[inline]
round(self) -> Self670     fn round(self) -> Self {
671         self.round()
672     }
673 }
674 
675 impl<T: Ceil, U> Ceil for Point2D<T, U> {
676     /// See [Point2D::ceil()](#method.ceil)
677     #[inline]
ceil(self) -> Self678     fn ceil(self) -> Self {
679         self.ceil()
680     }
681 }
682 
683 impl<T: Floor, U> Floor for Point2D<T, U> {
684     /// See [Point2D::floor()](#method.floor)
685     #[inline]
floor(self) -> Self686     fn floor(self) -> Self {
687         self.floor()
688     }
689 }
690 
691 impl<T: ApproxEq<T>, U> ApproxEq<Point2D<T, U>> for Point2D<T, U> {
692     #[inline]
approx_epsilon() -> Self693     fn approx_epsilon() -> Self {
694         point2(T::approx_epsilon(), T::approx_epsilon())
695     }
696 
697     #[inline]
approx_eq_eps(&self, other: &Self, eps: &Self) -> bool698     fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
699         self.x.approx_eq_eps(&other.x, &eps.x) && self.y.approx_eq_eps(&other.y, &eps.y)
700     }
701 }
702 
703 impl<T, U> Into<[T; 2]> for Point2D<T, U> {
into(self) -> [T; 2]704     fn into(self) -> [T; 2] {
705         [self.x, self.y]
706     }
707 }
708 
709 impl<T, U> From<[T; 2]> for Point2D<T, U> {
from([x, y]: [T; 2]) -> Self710     fn from([x, y]: [T; 2]) -> Self {
711         point2(x, y)
712     }
713 }
714 
715 impl<T, U> Into<(T, T)> for Point2D<T, U> {
into(self) -> (T, T)716     fn into(self) -> (T, T) {
717         (self.x, self.y)
718     }
719 }
720 
721 impl<T, U> From<(T, T)> for Point2D<T, U> {
from(tuple: (T, T)) -> Self722     fn from(tuple: (T, T)) -> Self {
723         point2(tuple.0, tuple.1)
724     }
725 }
726 
727 /// A 3d Point tagged with a unit.
728 #[repr(C)]
729 pub struct Point3D<T, U> {
730     pub x: T,
731     pub y: T,
732     pub z: T,
733     #[doc(hidden)]
734     pub _unit: PhantomData<U>,
735 }
736 
737 mint_vec!(Point3D[x, y, z] = Point3);
738 
739 impl<T: Copy, U> Copy for Point3D<T, U> {}
740 
741 impl<T: Clone, U> Clone for Point3D<T, U> {
clone(&self) -> Self742     fn clone(&self) -> Self {
743         Point3D {
744             x: self.x.clone(),
745             y: self.y.clone(),
746             z: self.z.clone(),
747             _unit: PhantomData,
748         }
749     }
750 }
751 
752 #[cfg(feature = "serde")]
753 impl<'de, T, U> serde::Deserialize<'de> for Point3D<T, U>
754 where
755     T: serde::Deserialize<'de>,
756 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de>,757     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
758     where
759         D: serde::Deserializer<'de>,
760     {
761         let (x, y, z) = serde::Deserialize::deserialize(deserializer)?;
762         Ok(Point3D {
763             x,
764             y,
765             z,
766             _unit: PhantomData,
767         })
768     }
769 }
770 
771 #[cfg(feature = "serde")]
772 impl<T, U> serde::Serialize for Point3D<T, U>
773 where
774     T: serde::Serialize,
775 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer,776     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
777     where
778         S: serde::Serializer,
779     {
780         (&self.x, &self.y, &self.z).serialize(serializer)
781     }
782 }
783 
784 impl<T, U> Eq for Point3D<T, U> where T: Eq {}
785 
786 impl<T, U> PartialEq for Point3D<T, U>
787 where
788     T: PartialEq,
789 {
eq(&self, other: &Self) -> bool790     fn eq(&self, other: &Self) -> bool {
791         self.x == other.x && self.y == other.y && self.z == other.z
792     }
793 }
794 
795 impl<T, U> Hash for Point3D<T, U>
796 where
797     T: Hash,
798 {
hash<H: core::hash::Hasher>(&self, h: &mut H)799     fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
800         self.x.hash(h);
801         self.y.hash(h);
802         self.z.hash(h);
803     }
804 }
805 
806 impl<T: fmt::Debug, U> fmt::Debug for Point3D<T, U> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result807     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
808         f.debug_tuple("")
809             .field(&self.x)
810             .field(&self.y)
811             .field(&self.z)
812             .finish()
813     }
814 }
815 
816 impl<T: Default, U> Default for Point3D<T, U> {
default() -> Self817     fn default() -> Self {
818         Point3D::new(Default::default(), Default::default(), Default::default())
819     }
820 }
821 
822 impl<T, U> Point3D<T, U> {
823     /// Constructor, setting all components to zero.
824     #[inline]
origin() -> Self where T: Zero,825     pub fn origin() -> Self
826     where
827         T: Zero,
828     {
829         point3(Zero::zero(), Zero::zero(), Zero::zero())
830     }
831 
832     /// The same as [`origin()`](#method.origin).
833     #[inline]
zero() -> Self where T: Zero,834     pub fn zero() -> Self
835     where
836         T: Zero,
837     {
838         Self::origin()
839     }
840 
841     /// Constructor taking scalar values directly.
842     #[inline]
new(x: T, y: T, z: T) -> Self843     pub const fn new(x: T, y: T, z: T) -> Self {
844         Point3D {
845             x,
846             y,
847             z,
848             _unit: PhantomData,
849         }
850     }
851 
852     /// Constructor taking properly Lengths instead of scalar values.
853     #[inline]
from_lengths(x: Length<T, U>, y: Length<T, U>, z: Length<T, U>) -> Self854     pub fn from_lengths(x: Length<T, U>, y: Length<T, U>, z: Length<T, U>) -> Self {
855         point3(x.0, y.0, z.0)
856     }
857 
858     /// Constructor setting all components to the same value.
859     #[inline]
splat(v: T) -> Self where T: Clone,860     pub fn splat(v: T) -> Self
861     where
862         T: Clone,
863     {
864         Point3D {
865             x: v.clone(),
866             y: v.clone(),
867             z: v,
868             _unit: PhantomData,
869         }
870     }
871 
872     /// Tag a unitless value with units.
873     #[inline]
from_untyped(p: Point3D<T, UnknownUnit>) -> Self874     pub fn from_untyped(p: Point3D<T, UnknownUnit>) -> Self {
875         point3(p.x, p.y, p.z)
876     }
877 }
878 
879 impl<T: Copy, U> Point3D<T, U> {
880     /// Cast this point into a vector.
881     ///
882     /// Equivalent to subtracting the origin to this point.
883     #[inline]
to_vector(self) -> Vector3D<T, U>884     pub fn to_vector(self) -> Vector3D<T, U> {
885         Vector3D {
886             x: self.x,
887             y: self.y,
888             z: self.z,
889             _unit: PhantomData,
890         }
891     }
892 
893     /// Returns a 2d point using this point's x and y coordinates
894     #[inline]
xy(self) -> Point2D<T, U>895     pub fn xy(self) -> Point2D<T, U> {
896         point2(self.x, self.y)
897     }
898 
899     /// Returns a 2d point using this point's x and z coordinates
900     #[inline]
xz(self) -> Point2D<T, U>901     pub fn xz(self) -> Point2D<T, U> {
902         point2(self.x, self.z)
903     }
904 
905     /// Returns a 2d point using this point's x and z coordinates
906     #[inline]
yz(self) -> Point2D<T, U>907     pub fn yz(self) -> Point2D<T, U> {
908         point2(self.y, self.z)
909     }
910 
911     /// Cast into an array with x, y and z.
912     ///
913     /// # Example
914     ///
915     /// ```rust
916     /// # use euclid::{Point3D, point3};
917     /// enum Mm {}
918     ///
919     /// let point: Point3D<_, Mm> = point3(1, -8, 0);
920     ///
921     /// assert_eq!(point.to_array(), [1, -8, 0]);
922     /// ```
923     #[inline]
to_array(self) -> [T; 3]924     pub fn to_array(self) -> [T; 3] {
925         [self.x, self.y, self.z]
926     }
927 
928     #[inline]
to_array_4d(self) -> [T; 4] where T: One,929     pub fn to_array_4d(self) -> [T; 4]
930     where
931         T: One,
932     {
933         [self.x, self.y, self.z, One::one()]
934     }
935 
936     /// Cast into a tuple with x, y and z.
937     ///
938     /// # Example
939     ///
940     /// ```rust
941     /// # use euclid::{Point3D, point3};
942     /// enum Mm {}
943     ///
944     /// let point: Point3D<_, Mm> = point3(1, -8, 0);
945     ///
946     /// assert_eq!(point.to_tuple(), (1, -8, 0));
947     /// ```
948     #[inline]
to_tuple(self) -> (T, T, T)949     pub fn to_tuple(self) -> (T, T, T) {
950         (self.x, self.y, self.z)
951     }
952 
953     #[inline]
to_tuple_4d(self) -> (T, T, T, T) where T: One,954     pub fn to_tuple_4d(self) -> (T, T, T, T)
955     where
956         T: One,
957     {
958         (self.x, self.y, self.z, One::one())
959     }
960 
961     /// Drop the units, preserving only the numeric value.
962     ///
963     /// # Example
964     ///
965     /// ```rust
966     /// # use euclid::{Point3D, point3};
967     /// enum Mm {}
968     ///
969     /// let point: Point3D<_, Mm> = point3(1, -8, 0);
970     ///
971     /// assert_eq!(point.x, point.to_untyped().x);
972     /// assert_eq!(point.y, point.to_untyped().y);
973     /// assert_eq!(point.z, point.to_untyped().z);
974     /// ```
975     #[inline]
to_untyped(self) -> Point3D<T, UnknownUnit>976     pub fn to_untyped(self) -> Point3D<T, UnknownUnit> {
977         point3(self.x, self.y, self.z)
978     }
979 
980     /// Cast the unit, preserving the numeric value.
981     ///
982     /// # Example
983     ///
984     /// ```rust
985     /// # use euclid::{Point3D, point3};
986     /// enum Mm {}
987     /// enum Cm {}
988     ///
989     /// let point: Point3D<_, Mm> = point3(1, -8, 0);
990     ///
991     /// assert_eq!(point.x, point.cast_unit::<Cm>().x);
992     /// assert_eq!(point.y, point.cast_unit::<Cm>().y);
993     /// assert_eq!(point.z, point.cast_unit::<Cm>().z);
994     /// ```
995     #[inline]
cast_unit<V>(self) -> Point3D<T, V>996     pub fn cast_unit<V>(self) -> Point3D<T, V> {
997         point3(self.x, self.y, self.z)
998     }
999 
1000     /// Convert into a 2d point.
1001     #[inline]
to_2d(self) -> Point2D<T, U>1002     pub fn to_2d(self) -> Point2D<T, U> {
1003         self.xy()
1004     }
1005 
1006     /// Rounds each component to the nearest integer value.
1007     ///
1008     /// This behavior is preserved for negative values (unlike the basic cast).
1009     ///
1010     /// ```rust
1011     /// # use euclid::point3;
1012     /// enum Mm {}
1013     ///
1014     /// assert_eq!(point3::<_, Mm>(-0.1, -0.8, 0.4).round(), point3::<_, Mm>(0.0, -1.0, 0.0))
1015     /// ```
1016     #[inline]
1017     #[must_use]
round(self) -> Self where T: Round,1018     pub fn round(self) -> Self
1019     where
1020         T: Round,
1021     {
1022         point3(self.x.round(), self.y.round(), self.z.round())
1023     }
1024 
1025     /// Rounds each component to the smallest integer equal or greater than the original value.
1026     ///
1027     /// This behavior is preserved for negative values (unlike the basic cast).
1028     ///
1029     /// ```rust
1030     /// # use euclid::point3;
1031     /// enum Mm {}
1032     ///
1033     /// assert_eq!(point3::<_, Mm>(-0.1, -0.8, 0.4).ceil(), point3::<_, Mm>(0.0, 0.0, 1.0))
1034     /// ```
1035     #[inline]
1036     #[must_use]
ceil(self) -> Self where T: Ceil,1037     pub fn ceil(self) -> Self
1038     where
1039         T: Ceil,
1040     {
1041         point3(self.x.ceil(), self.y.ceil(), self.z.ceil())
1042     }
1043 
1044     /// Rounds each component to the biggest integer equal or lower than the original value.
1045     ///
1046     /// This behavior is preserved for negative values (unlike the basic cast).
1047     ///
1048     /// ```rust
1049     /// # use euclid::point3;
1050     /// enum Mm {}
1051     ///
1052     /// assert_eq!(point3::<_, Mm>(-0.1, -0.8, 0.4).floor(), point3::<_, Mm>(-1.0, -1.0, 0.0))
1053     /// ```
1054     #[inline]
1055     #[must_use]
floor(self) -> Self where T: Floor,1056     pub fn floor(self) -> Self
1057     where
1058         T: Floor,
1059     {
1060         point3(self.x.floor(), self.y.floor(), self.z.floor())
1061     }
1062 
1063     /// Linearly interpolate between this point and another point.
1064     ///
1065     /// # Example
1066     ///
1067     /// ```rust
1068     /// use euclid::point3;
1069     /// use euclid::default::Point3D;
1070     ///
1071     /// let from: Point3D<_> = point3(0.0, 10.0, -1.0);
1072     /// let to:  Point3D<_> = point3(8.0, -4.0,  0.0);
1073     ///
1074     /// assert_eq!(from.lerp(to, -1.0), point3(-8.0,  24.0, -2.0));
1075     /// assert_eq!(from.lerp(to,  0.0), point3( 0.0,  10.0, -1.0));
1076     /// assert_eq!(from.lerp(to,  0.5), point3( 4.0,   3.0, -0.5));
1077     /// assert_eq!(from.lerp(to,  1.0), point3( 8.0,  -4.0,  0.0));
1078     /// assert_eq!(from.lerp(to,  2.0), point3(16.0, -18.0,  1.0));
1079     /// ```
1080     #[inline]
lerp(self, other: Self, t: T) -> Self where T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,1081     pub fn lerp(self, other: Self, t: T) -> Self
1082     where
1083         T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
1084     {
1085         let one_t = T::one() - t;
1086         point3(
1087             one_t * self.x + t * other.x,
1088             one_t * self.y + t * other.y,
1089             one_t * self.z + t * other.z,
1090         )
1091     }
1092 }
1093 
1094 impl<T: PartialOrd, U> Point3D<T, U> {
1095     #[inline]
min(self, other: Self) -> Self1096     pub fn min(self, other: Self) -> Self {
1097         point3(
1098             min(self.x, other.x),
1099             min(self.y, other.y),
1100             min(self.z, other.z),
1101         )
1102     }
1103 
1104     #[inline]
max(self, other: Self) -> Self1105     pub fn max(self, other: Self) -> Self {
1106         point3(
1107             max(self.x, other.x),
1108             max(self.y, other.y),
1109             max(self.z, other.z),
1110         )
1111     }
1112 
1113     /// Returns the point each component of which clamped by corresponding
1114     /// components of `start` and `end`.
1115     ///
1116     /// Shortcut for `self.max(start).min(end)`.
1117     #[inline]
clamp(self, start: Self, end: Self) -> Self where T: Copy,1118     pub fn clamp(self, start: Self, end: Self) -> Self
1119     where
1120         T: Copy,
1121     {
1122         self.max(start).min(end)
1123     }
1124 }
1125 
1126 impl<T: NumCast + Copy, U> Point3D<T, U> {
1127     /// Cast from one numeric representation to another, preserving the units.
1128     ///
1129     /// When casting from floating point to integer coordinates, the decimals are truncated
1130     /// as one would expect from a simple cast, but this behavior does not always make sense
1131     /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
1132     #[inline]
cast<NewT: NumCast>(self) -> Point3D<NewT, U>1133     pub fn cast<NewT: NumCast>(self) -> Point3D<NewT, U> {
1134         self.try_cast().unwrap()
1135     }
1136 
1137     /// Fallible cast from one numeric representation to another, preserving the units.
1138     ///
1139     /// When casting from floating point to integer coordinates, the decimals are truncated
1140     /// as one would expect from a simple cast, but this behavior does not always make sense
1141     /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
try_cast<NewT: NumCast>(self) -> Option<Point3D<NewT, U>>1142     pub fn try_cast<NewT: NumCast>(self) -> Option<Point3D<NewT, U>> {
1143         match (
1144             NumCast::from(self.x),
1145             NumCast::from(self.y),
1146             NumCast::from(self.z),
1147         ) {
1148             (Some(x), Some(y), Some(z)) => Some(point3(x, y, z)),
1149             _ => None,
1150         }
1151     }
1152 
1153     // Convenience functions for common casts
1154 
1155     /// Cast into an `f32` point.
1156     #[inline]
to_f32(self) -> Point3D<f32, U>1157     pub fn to_f32(self) -> Point3D<f32, U> {
1158         self.cast()
1159     }
1160 
1161     /// Cast into an `f64` point.
1162     #[inline]
to_f64(self) -> Point3D<f64, U>1163     pub fn to_f64(self) -> Point3D<f64, U> {
1164         self.cast()
1165     }
1166 
1167     /// Cast into an `usize` point, truncating decimals if any.
1168     ///
1169     /// When casting from floating point points, it is worth considering whether
1170     /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
1171     /// the desired conversion behavior.
1172     #[inline]
to_usize(self) -> Point3D<usize, U>1173     pub fn to_usize(self) -> Point3D<usize, U> {
1174         self.cast()
1175     }
1176 
1177     /// Cast into an `u32` point, truncating decimals if any.
1178     ///
1179     /// When casting from floating point points, it is worth considering whether
1180     /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
1181     /// the desired conversion behavior.
1182     #[inline]
to_u32(self) -> Point3D<u32, U>1183     pub fn to_u32(self) -> Point3D<u32, U> {
1184         self.cast()
1185     }
1186 
1187     /// Cast into an `i32` point, truncating decimals if any.
1188     ///
1189     /// When casting from floating point points, it is worth considering whether
1190     /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
1191     /// the desired conversion behavior.
1192     #[inline]
to_i32(self) -> Point3D<i32, U>1193     pub fn to_i32(self) -> Point3D<i32, U> {
1194         self.cast()
1195     }
1196 
1197     /// Cast into an `i64` point, truncating decimals if any.
1198     ///
1199     /// When casting from floating point points, it is worth considering whether
1200     /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
1201     /// the desired conversion behavior.
1202     #[inline]
to_i64(self) -> Point3D<i64, U>1203     pub fn to_i64(self) -> Point3D<i64, U> {
1204         self.cast()
1205     }
1206 }
1207 
1208 impl<T: Float, U> Point3D<T, U> {
1209     /// Returns true if all members are finite.
1210     #[inline]
is_finite(self) -> bool1211     pub fn is_finite(self) -> bool {
1212         self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
1213     }
1214 }
1215 
1216 impl<T: Copy + Add<T, Output = T>, U> Point3D<T, U> {
1217     #[inline]
add_size(self, other: Size3D<T, U>) -> Self1218     pub fn add_size(self, other: Size3D<T, U>) -> Self {
1219         point3(
1220             self.x + other.width,
1221             self.y + other.height,
1222             self.z + other.depth,
1223         )
1224     }
1225 }
1226 
1227 impl<T: Float + Sub<T, Output = T>, U> Point3D<T, U> {
1228     #[inline]
distance_to(self, other: Self) -> T1229     pub fn distance_to(self, other: Self) -> T {
1230         (self - other).length()
1231     }
1232 }
1233 
1234 impl<T: Neg, U> Neg for Point3D<T, U> {
1235     type Output = Point3D<T::Output, U>;
1236 
1237     #[inline]
neg(self) -> Self::Output1238     fn neg(self) -> Self::Output {
1239         point3(-self.x, -self.y, -self.z)
1240     }
1241 }
1242 
1243 impl<T: Add, U> Add<Size3D<T, U>> for Point3D<T, U> {
1244     type Output = Point3D<T::Output, U>;
1245 
1246     #[inline]
add(self, other: Size3D<T, U>) -> Self::Output1247     fn add(self, other: Size3D<T, U>) -> Self::Output {
1248         point3(
1249             self.x + other.width,
1250             self.y + other.height,
1251             self.z + other.depth,
1252         )
1253     }
1254 }
1255 
1256 impl<T: AddAssign, U> AddAssign<Size3D<T, U>> for Point3D<T, U> {
1257     #[inline]
add_assign(&mut self, other: Size3D<T, U>)1258     fn add_assign(&mut self, other: Size3D<T, U>) {
1259         self.x += other.width;
1260         self.y += other.height;
1261         self.z += other.depth;
1262     }
1263 }
1264 
1265 impl<T: Add, U> Add<Vector3D<T, U>> for Point3D<T, U> {
1266     type Output = Point3D<T::Output, U>;
1267 
1268     #[inline]
add(self, other: Vector3D<T, U>) -> Self::Output1269     fn add(self, other: Vector3D<T, U>) -> Self::Output {
1270         point3(self.x + other.x, self.y + other.y, self.z + other.z)
1271     }
1272 }
1273 
1274 impl<T: Copy + Add<T, Output = T>, U> AddAssign<Vector3D<T, U>> for Point3D<T, U> {
1275     #[inline]
add_assign(&mut self, other: Vector3D<T, U>)1276     fn add_assign(&mut self, other: Vector3D<T, U>) {
1277         *self = *self + other
1278     }
1279 }
1280 
1281 impl<T: Sub, U> Sub for Point3D<T, U> {
1282     type Output = Vector3D<T::Output, U>;
1283 
1284     #[inline]
sub(self, other: Self) -> Self::Output1285     fn sub(self, other: Self) -> Self::Output {
1286         vec3(self.x - other.x, self.y - other.y, self.z - other.z)
1287     }
1288 }
1289 
1290 impl<T: Sub, U> Sub<Size3D<T, U>> for Point3D<T, U> {
1291     type Output = Point3D<T::Output, U>;
1292 
1293     #[inline]
sub(self, other: Size3D<T, U>) -> Self::Output1294     fn sub(self, other: Size3D<T, U>) -> Self::Output {
1295         point3(
1296             self.x - other.width,
1297             self.y - other.height,
1298             self.z - other.depth,
1299         )
1300     }
1301 }
1302 
1303 impl<T: SubAssign, U> SubAssign<Size3D<T, U>> for Point3D<T, U> {
1304     #[inline]
sub_assign(&mut self, other: Size3D<T, U>)1305     fn sub_assign(&mut self, other: Size3D<T, U>) {
1306         self.x -= other.width;
1307         self.y -= other.height;
1308         self.z -= other.depth;
1309     }
1310 }
1311 
1312 impl<T: Sub, U> Sub<Vector3D<T, U>> for Point3D<T, U> {
1313     type Output = Point3D<T::Output, U>;
1314 
1315     #[inline]
sub(self, other: Vector3D<T, U>) -> Self::Output1316     fn sub(self, other: Vector3D<T, U>) -> Self::Output {
1317         point3(self.x - other.x, self.y - other.y, self.z - other.z)
1318     }
1319 }
1320 
1321 impl<T: Copy + Sub<T, Output = T>, U> SubAssign<Vector3D<T, U>> for Point3D<T, U> {
1322     #[inline]
sub_assign(&mut self, other: Vector3D<T, U>)1323     fn sub_assign(&mut self, other: Vector3D<T, U>) {
1324         *self = *self - other
1325     }
1326 }
1327 
1328 impl<T: Copy + Mul, U> Mul<T> for Point3D<T, U> {
1329     type Output = Point3D<T::Output, U>;
1330 
1331     #[inline]
mul(self, scale: T) -> Self::Output1332     fn mul(self, scale: T) -> Self::Output {
1333         point3(
1334             self.x * scale,
1335             self.y * scale,
1336             self.z * scale,
1337         )
1338     }
1339 }
1340 
1341 impl<T: Copy + MulAssign, U> MulAssign<T> for Point3D<T, U> {
1342     #[inline]
mul_assign(&mut self, scale: T)1343     fn mul_assign(&mut self, scale: T) {
1344         self.x *= scale;
1345         self.y *= scale;
1346         self.z *= scale;
1347     }
1348 }
1349 
1350 impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Point3D<T, U1> {
1351     type Output = Point3D<T::Output, U2>;
1352 
1353     #[inline]
mul(self, scale: Scale<T, U1, U2>) -> Self::Output1354     fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
1355         point3(
1356             self.x * scale.0,
1357             self.y * scale.0,
1358             self.z * scale.0,
1359         )
1360     }
1361 }
1362 
1363 impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Point3D<T, U> {
1364     #[inline]
mul_assign(&mut self, scale: Scale<T, U, U>)1365     fn mul_assign(&mut self, scale: Scale<T, U, U>) {
1366         *self *= scale.0;
1367     }
1368 }
1369 
1370 impl<T: Copy + Div, U> Div<T> for Point3D<T, U> {
1371     type Output = Point3D<T::Output, U>;
1372 
1373     #[inline]
div(self, scale: T) -> Self::Output1374     fn div(self, scale: T) -> Self::Output {
1375         point3(
1376             self.x / scale,
1377             self.y / scale,
1378             self.z / scale,
1379         )
1380     }
1381 }
1382 
1383 impl<T: Copy + DivAssign, U> DivAssign<T> for Point3D<T, U> {
1384     #[inline]
div_assign(&mut self, scale: T)1385     fn div_assign(&mut self, scale: T) {
1386         self.x /= scale;
1387         self.y /= scale;
1388         self.z /= scale;
1389     }
1390 }
1391 
1392 impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Point3D<T, U2> {
1393     type Output = Point3D<T::Output, U1>;
1394 
1395     #[inline]
div(self, scale: Scale<T, U1, U2>) -> Self::Output1396     fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
1397         point3(
1398             self.x / scale.0,
1399             self.y / scale.0,
1400             self.z / scale.0,
1401         )
1402     }
1403 }
1404 
1405 impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Point3D<T, U> {
1406     #[inline]
div_assign(&mut self, scale: Scale<T, U, U>)1407     fn div_assign(&mut self, scale: Scale<T, U, U>) {
1408         *self /= scale.0;
1409     }
1410 }
1411 
1412 impl<T: Zero, U> Zero for Point3D<T, U> {
1413     #[inline]
zero() -> Self1414     fn zero() -> Self {
1415         Self::origin()
1416     }
1417 }
1418 
1419 impl<T: Round, U> Round for Point3D<T, U> {
1420     /// See [Point3D::round()](#method.round)
1421     #[inline]
round(self) -> Self1422     fn round(self) -> Self {
1423         self.round()
1424     }
1425 }
1426 
1427 impl<T: Ceil, U> Ceil for Point3D<T, U> {
1428     /// See [Point3D::ceil()](#method.ceil)
1429     #[inline]
ceil(self) -> Self1430     fn ceil(self) -> Self {
1431         self.ceil()
1432     }
1433 }
1434 
1435 impl<T: Floor, U> Floor for Point3D<T, U> {
1436     /// See [Point3D::floor()](#method.floor)
1437     #[inline]
floor(self) -> Self1438     fn floor(self) -> Self {
1439         self.floor()
1440     }
1441 }
1442 
1443 impl<T: ApproxEq<T>, U> ApproxEq<Point3D<T, U>> for Point3D<T, U> {
1444     #[inline]
approx_epsilon() -> Self1445     fn approx_epsilon() -> Self {
1446         point3(
1447             T::approx_epsilon(),
1448             T::approx_epsilon(),
1449             T::approx_epsilon(),
1450         )
1451     }
1452 
1453     #[inline]
approx_eq_eps(&self, other: &Self, eps: &Self) -> bool1454     fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
1455         self.x.approx_eq_eps(&other.x, &eps.x)
1456             && self.y.approx_eq_eps(&other.y, &eps.y)
1457             && self.z.approx_eq_eps(&other.z, &eps.z)
1458     }
1459 }
1460 
1461 impl<T, U> Into<[T; 3]> for Point3D<T, U> {
into(self) -> [T; 3]1462     fn into(self) -> [T; 3] {
1463         [self.x, self.y, self.z]
1464     }
1465 }
1466 
1467 impl<T, U> From<[T; 3]> for Point3D<T, U> {
from([x, y, z]: [T; 3]) -> Self1468     fn from([x, y, z]: [T; 3]) -> Self {
1469         point3(x, y, z)
1470     }
1471 }
1472 
1473 impl<T, U> Into<(T, T, T)> for Point3D<T, U> {
into(self) -> (T, T, T)1474     fn into(self) -> (T, T, T) {
1475         (self.x, self.y, self.z)
1476     }
1477 }
1478 
1479 impl<T, U> From<(T, T, T)> for Point3D<T, U> {
from(tuple: (T, T, T)) -> Self1480     fn from(tuple: (T, T, T)) -> Self {
1481         point3(tuple.0, tuple.1, tuple.2)
1482     }
1483 }
1484 
1485 /// Shorthand for `Point2D::new(x, y)`.
1486 #[inline]
point2<T, U>(x: T, y: T) -> Point2D<T, U>1487 pub const fn point2<T, U>(x: T, y: T) -> Point2D<T, U> {
1488     Point2D {
1489         x,
1490         y,
1491         _unit: PhantomData,
1492     }
1493 }
1494 
1495 /// Shorthand for `Point3D::new(x, y)`.
1496 #[inline]
point3<T, U>(x: T, y: T, z: T) -> Point3D<T, U>1497 pub const fn point3<T, U>(x: T, y: T, z: T) -> Point3D<T, U> {
1498     Point3D {
1499         x,
1500         y,
1501         z,
1502         _unit: PhantomData,
1503     }
1504 }
1505 
1506 #[cfg(test)]
1507 mod point2d {
1508     use crate::default::Point2D;
1509     use crate::point2;
1510 
1511     #[cfg(feature = "mint")]
1512     use mint;
1513 
1514     #[test]
test_min()1515     pub fn test_min() {
1516         let p1 = Point2D::new(1.0, 3.0);
1517         let p2 = Point2D::new(2.0, 2.0);
1518 
1519         let result = p1.min(p2);
1520 
1521         assert_eq!(result, Point2D::new(1.0, 2.0));
1522     }
1523 
1524     #[test]
test_max()1525     pub fn test_max() {
1526         let p1 = Point2D::new(1.0, 3.0);
1527         let p2 = Point2D::new(2.0, 2.0);
1528 
1529         let result = p1.max(p2);
1530 
1531         assert_eq!(result, Point2D::new(2.0, 3.0));
1532     }
1533 
1534     #[cfg(feature = "mint")]
1535     #[test]
test_mint()1536     pub fn test_mint() {
1537         let p1 = Point2D::new(1.0, 3.0);
1538         let pm: mint::Point2<_> = p1.into();
1539         let p2 = Point2D::from(pm);
1540 
1541         assert_eq!(p1, p2);
1542     }
1543 
1544     #[test]
test_conv_vector()1545     pub fn test_conv_vector() {
1546         for i in 0..100 {
1547             // We don't care about these values as long as they are not the same.
1548             let x = i as f32 * 0.012345;
1549             let y = i as f32 * 0.987654;
1550             let p: Point2D<f32> = point2(x, y);
1551             assert_eq!(p.to_vector().to_point(), p);
1552         }
1553     }
1554 
1555     #[test]
test_swizzling()1556     pub fn test_swizzling() {
1557         let p: Point2D<i32> = point2(1, 2);
1558         assert_eq!(p.yx(), point2(2, 1));
1559     }
1560 
1561     #[test]
test_distance_to()1562     pub fn test_distance_to() {
1563         let p1 = Point2D::new(1.0, 2.0);
1564         let p2 = Point2D::new(2.0, 2.0);
1565 
1566         assert_eq!(p1.distance_to(p2), 1.0);
1567 
1568         let p1 = Point2D::new(1.0, 2.0);
1569         let p2 = Point2D::new(1.0, 4.0);
1570 
1571         assert_eq!(p1.distance_to(p2), 2.0);
1572     }
1573 
1574     mod ops {
1575         use crate::default::Point2D;
1576         use crate::scale::Scale;
1577         use crate::{size2, vec2, Vector2D};
1578 
1579         pub enum Mm {}
1580         pub enum Cm {}
1581 
1582         pub type Point2DMm<T> = crate::Point2D<T, Mm>;
1583         pub type Point2DCm<T> = crate::Point2D<T, Cm>;
1584 
1585         #[test]
test_neg()1586         pub fn test_neg() {
1587             assert_eq!(-Point2D::new(1.0, 2.0), Point2D::new(-1.0, -2.0));
1588             assert_eq!(-Point2D::new(0.0, 0.0), Point2D::new(-0.0, -0.0));
1589             assert_eq!(-Point2D::new(-1.0, -2.0), Point2D::new(1.0, 2.0));
1590         }
1591 
1592         #[test]
test_add_size()1593         pub fn test_add_size() {
1594             let p1 = Point2DMm::new(1.0, 2.0);
1595             let p2 = size2(3.0, 4.0);
1596 
1597             let result = p1 + p2;
1598 
1599             assert_eq!(result, Point2DMm::new(4.0, 6.0));
1600         }
1601 
1602         #[test]
test_add_assign_size()1603         pub fn test_add_assign_size() {
1604             let mut p1 = Point2DMm::new(1.0, 2.0);
1605 
1606             p1 += size2(3.0, 4.0);
1607 
1608             assert_eq!(p1, Point2DMm::new(4.0, 6.0));
1609         }
1610 
1611         #[test]
test_add_vec()1612         pub fn test_add_vec() {
1613             let p1 = Point2DMm::new(1.0, 2.0);
1614             let p2 = vec2(3.0, 4.0);
1615 
1616             let result = p1 + p2;
1617 
1618             assert_eq!(result, Point2DMm::new(4.0, 6.0));
1619         }
1620 
1621         #[test]
test_add_assign_vec()1622         pub fn test_add_assign_vec() {
1623             let mut p1 = Point2DMm::new(1.0, 2.0);
1624 
1625             p1 += vec2(3.0, 4.0);
1626 
1627             assert_eq!(p1, Point2DMm::new(4.0, 6.0));
1628         }
1629 
1630         #[test]
test_sub()1631         pub fn test_sub() {
1632             let p1 = Point2DMm::new(1.0, 2.0);
1633             let p2 = Point2DMm::new(3.0, 4.0);
1634 
1635             let result = p1 - p2;
1636 
1637             assert_eq!(result, Vector2D::<_, Mm>::new(-2.0, -2.0));
1638         }
1639 
1640         #[test]
test_sub_size()1641         pub fn test_sub_size() {
1642             let p1 = Point2DMm::new(1.0, 2.0);
1643             let p2 = size2(3.0, 4.0);
1644 
1645             let result = p1 - p2;
1646 
1647             assert_eq!(result, Point2DMm::new(-2.0, -2.0));
1648         }
1649 
1650         #[test]
test_sub_assign_size()1651         pub fn test_sub_assign_size() {
1652             let mut p1 = Point2DMm::new(1.0, 2.0);
1653 
1654             p1 -= size2(3.0, 4.0);
1655 
1656             assert_eq!(p1, Point2DMm::new(-2.0, -2.0));
1657         }
1658 
1659         #[test]
test_sub_vec()1660         pub fn test_sub_vec() {
1661             let p1 = Point2DMm::new(1.0, 2.0);
1662             let p2 = vec2(3.0, 4.0);
1663 
1664             let result = p1 - p2;
1665 
1666             assert_eq!(result, Point2DMm::new(-2.0, -2.0));
1667         }
1668 
1669         #[test]
test_sub_assign_vec()1670         pub fn test_sub_assign_vec() {
1671             let mut p1 = Point2DMm::new(1.0, 2.0);
1672 
1673             p1 -= vec2(3.0, 4.0);
1674 
1675             assert_eq!(p1, Point2DMm::new(-2.0, -2.0));
1676         }
1677 
1678         #[test]
test_mul_scalar()1679         pub fn test_mul_scalar() {
1680             let p1: Point2D<f32> = Point2D::new(3.0, 5.0);
1681 
1682             let result = p1 * 5.0;
1683 
1684             assert_eq!(result, Point2D::new(15.0, 25.0));
1685         }
1686 
1687         #[test]
test_mul_assign_scalar()1688         pub fn test_mul_assign_scalar() {
1689             let mut p1 = Point2D::new(3.0, 5.0);
1690 
1691             p1 *= 5.0;
1692 
1693             assert_eq!(p1, Point2D::new(15.0, 25.0));
1694         }
1695 
1696         #[test]
test_mul_scale()1697         pub fn test_mul_scale() {
1698             let p1 = Point2DMm::new(1.0, 2.0);
1699             let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
1700 
1701             let result = p1 * cm_per_mm;
1702 
1703             assert_eq!(result, Point2DCm::new(0.1, 0.2));
1704         }
1705 
1706         #[test]
test_mul_assign_scale()1707         pub fn test_mul_assign_scale() {
1708             let mut p1 = Point2DMm::new(1.0, 2.0);
1709             let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
1710 
1711             p1 *= scale;
1712 
1713             assert_eq!(p1, Point2DMm::new(0.1, 0.2));
1714         }
1715 
1716         #[test]
test_div_scalar()1717         pub fn test_div_scalar() {
1718             let p1: Point2D<f32> = Point2D::new(15.0, 25.0);
1719 
1720             let result = p1 / 5.0;
1721 
1722             assert_eq!(result, Point2D::new(3.0, 5.0));
1723         }
1724 
1725         #[test]
test_div_assign_scalar()1726         pub fn test_div_assign_scalar() {
1727             let mut p1: Point2D<f32> = Point2D::new(15.0, 25.0);
1728 
1729             p1 /= 5.0;
1730 
1731             assert_eq!(p1, Point2D::new(3.0, 5.0));
1732         }
1733 
1734         #[test]
test_div_scale()1735         pub fn test_div_scale() {
1736             let p1 = Point2DCm::new(0.1, 0.2);
1737             let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
1738 
1739             let result = p1 / cm_per_mm;
1740 
1741             assert_eq!(result, Point2DMm::new(1.0, 2.0));
1742         }
1743 
1744         #[test]
test_div_assign_scale()1745         pub fn test_div_assign_scale() {
1746             let mut p1 = Point2DMm::new(0.1, 0.2);
1747             let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
1748 
1749             p1 /= scale;
1750 
1751             assert_eq!(p1, Point2DMm::new(1.0, 2.0));
1752         }
1753 
1754         #[test]
test_point_debug_formatting()1755         pub fn test_point_debug_formatting() {
1756             let n = 1.23456789;
1757             let p1 = Point2D::new(n, -n);
1758             let should_be = format!("({:.4}, {:.4})", n, -n);
1759 
1760             let got = format!("{:.4?}", p1);
1761 
1762             assert_eq!(got, should_be);
1763         }
1764     }
1765 }
1766 
1767 #[cfg(test)]
1768 mod point3d {
1769     use crate::default;
1770     use crate::default::Point3D;
1771     use crate::{point2, point3};
1772     #[cfg(feature = "mint")]
1773     use mint;
1774 
1775     #[test]
test_min()1776     pub fn test_min() {
1777         let p1 = Point3D::new(1.0, 3.0, 5.0);
1778         let p2 = Point3D::new(2.0, 2.0, -1.0);
1779 
1780         let result = p1.min(p2);
1781 
1782         assert_eq!(result, Point3D::new(1.0, 2.0, -1.0));
1783     }
1784 
1785     #[test]
test_max()1786     pub fn test_max() {
1787         let p1 = Point3D::new(1.0, 3.0, 5.0);
1788         let p2 = Point3D::new(2.0, 2.0, -1.0);
1789 
1790         let result = p1.max(p2);
1791 
1792         assert_eq!(result, Point3D::new(2.0, 3.0, 5.0));
1793     }
1794 
1795     #[test]
test_conv_vector()1796     pub fn test_conv_vector() {
1797         use crate::point3;
1798         for i in 0..100 {
1799             // We don't care about these values as long as they are not the same.
1800             let x = i as f32 * 0.012345;
1801             let y = i as f32 * 0.987654;
1802             let z = x * y;
1803             let p: Point3D<f32> = point3(x, y, z);
1804             assert_eq!(p.to_vector().to_point(), p);
1805         }
1806     }
1807 
1808     #[test]
test_swizzling()1809     pub fn test_swizzling() {
1810         let p: default::Point3D<i32> = point3(1, 2, 3);
1811         assert_eq!(p.xy(), point2(1, 2));
1812         assert_eq!(p.xz(), point2(1, 3));
1813         assert_eq!(p.yz(), point2(2, 3));
1814     }
1815 
1816     #[test]
test_distance_to()1817     pub fn test_distance_to() {
1818         let p1 = Point3D::new(1.0, 2.0, 3.0);
1819         let p2 = Point3D::new(2.0, 2.0, 3.0);
1820 
1821         assert_eq!(p1.distance_to(p2), 1.0);
1822 
1823         let p1 = Point3D::new(1.0, 2.0, 3.0);
1824         let p2 = Point3D::new(1.0, 4.0, 3.0);
1825 
1826         assert_eq!(p1.distance_to(p2), 2.0);
1827 
1828         let p1 = Point3D::new(1.0, 2.0, 3.0);
1829         let p2 = Point3D::new(1.0, 2.0, 6.0);
1830 
1831         assert_eq!(p1.distance_to(p2), 3.0);
1832     }
1833 
1834     #[cfg(feature = "mint")]
1835     #[test]
test_mint()1836     pub fn test_mint() {
1837         let p1 = Point3D::new(1.0, 3.0, 5.0);
1838         let pm: mint::Point3<_> = p1.into();
1839         let p2 = Point3D::from(pm);
1840 
1841         assert_eq!(p1, p2);
1842     }
1843 
1844     mod ops {
1845         use crate::default::Point3D;
1846         use crate::scale::Scale;
1847         use crate::{size3, vec3, Vector3D};
1848 
1849         pub enum Mm {}
1850         pub enum Cm {}
1851 
1852         pub type Point3DMm<T> = crate::Point3D<T, Mm>;
1853         pub type Point3DCm<T> = crate::Point3D<T, Cm>;
1854 
1855         #[test]
test_neg()1856         pub fn test_neg() {
1857             assert_eq!(-Point3D::new(1.0, 2.0, 3.0), Point3D::new(-1.0, -2.0, -3.0));
1858             assert_eq!(-Point3D::new(0.0, 0.0, 0.0), Point3D::new(-0.0, -0.0, -0.0));
1859             assert_eq!(-Point3D::new(-1.0, -2.0, -3.0), Point3D::new(1.0, 2.0, 3.0));
1860         }
1861 
1862         #[test]
test_add_size()1863         pub fn test_add_size() {
1864             let p1 = Point3DMm::new(1.0, 2.0, 3.0);
1865             let p2 = size3(4.0, 5.0, 6.0);
1866 
1867             let result = p1 + p2;
1868 
1869             assert_eq!(result, Point3DMm::new(5.0, 7.0, 9.0));
1870         }
1871 
1872         #[test]
test_add_assign_size()1873         pub fn test_add_assign_size() {
1874             let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
1875 
1876             p1 += size3(4.0, 5.0, 6.0);
1877 
1878             assert_eq!(p1, Point3DMm::new(5.0, 7.0, 9.0));
1879         }
1880 
1881         #[test]
test_add_vec()1882         pub fn test_add_vec() {
1883             let p1 = Point3DMm::new(1.0, 2.0, 3.0);
1884             let p2 = vec3(4.0, 5.0, 6.0);
1885 
1886             let result = p1 + p2;
1887 
1888             assert_eq!(result, Point3DMm::new(5.0, 7.0, 9.0));
1889         }
1890 
1891         #[test]
test_add_assign_vec()1892         pub fn test_add_assign_vec() {
1893             let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
1894 
1895             p1 += vec3(4.0, 5.0, 6.0);
1896 
1897             assert_eq!(p1, Point3DMm::new(5.0, 7.0, 9.0));
1898         }
1899 
1900         #[test]
test_sub()1901         pub fn test_sub() {
1902             let p1 = Point3DMm::new(1.0, 2.0, 3.0);
1903             let p2 = Point3DMm::new(4.0, 5.0, 6.0);
1904 
1905             let result = p1 - p2;
1906 
1907             assert_eq!(result, Vector3D::<_, Mm>::new(-3.0, -3.0, -3.0));
1908         }
1909 
1910         #[test]
test_sub_size()1911         pub fn test_sub_size() {
1912             let p1 = Point3DMm::new(1.0, 2.0, 3.0);
1913             let p2 = size3(4.0, 5.0, 6.0);
1914 
1915             let result = p1 - p2;
1916 
1917             assert_eq!(result, Point3DMm::new(-3.0, -3.0, -3.0));
1918         }
1919 
1920         #[test]
test_sub_assign_size()1921         pub fn test_sub_assign_size() {
1922             let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
1923 
1924             p1 -= size3(4.0, 5.0, 6.0);
1925 
1926             assert_eq!(p1, Point3DMm::new(-3.0, -3.0, -3.0));
1927         }
1928 
1929         #[test]
test_sub_vec()1930         pub fn test_sub_vec() {
1931             let p1 = Point3DMm::new(1.0, 2.0, 3.0);
1932             let p2 = vec3(4.0, 5.0, 6.0);
1933 
1934             let result = p1 - p2;
1935 
1936             assert_eq!(result, Point3DMm::new(-3.0, -3.0, -3.0));
1937         }
1938 
1939         #[test]
test_sub_assign_vec()1940         pub fn test_sub_assign_vec() {
1941             let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
1942 
1943             p1 -= vec3(4.0, 5.0, 6.0);
1944 
1945             assert_eq!(p1, Point3DMm::new(-3.0, -3.0, -3.0));
1946         }
1947 
1948         #[test]
test_mul_scalar()1949         pub fn test_mul_scalar() {
1950             let p1: Point3D<f32> = Point3D::new(3.0, 5.0, 7.0);
1951 
1952             let result = p1 * 5.0;
1953 
1954             assert_eq!(result, Point3D::new(15.0, 25.0, 35.0));
1955         }
1956 
1957         #[test]
test_mul_assign_scalar()1958         pub fn test_mul_assign_scalar() {
1959             let mut p1: Point3D<f32> = Point3D::new(3.0, 5.0, 7.0);
1960 
1961             p1 *= 5.0;
1962 
1963             assert_eq!(p1, Point3D::new(15.0, 25.0, 35.0));
1964         }
1965 
1966         #[test]
test_mul_scale()1967         pub fn test_mul_scale() {
1968             let p1 = Point3DMm::new(1.0, 2.0, 3.0);
1969             let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
1970 
1971             let result = p1 * cm_per_mm;
1972 
1973             assert_eq!(result, Point3DCm::new(0.1, 0.2, 0.3));
1974         }
1975 
1976         #[test]
test_mul_assign_scale()1977         pub fn test_mul_assign_scale() {
1978             let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
1979             let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
1980 
1981             p1 *= scale;
1982 
1983             assert_eq!(p1, Point3DMm::new(0.1, 0.2, 0.3));
1984         }
1985 
1986         #[test]
test_div_scalar()1987         pub fn test_div_scalar() {
1988             let p1: Point3D<f32> = Point3D::new(15.0, 25.0, 35.0);
1989 
1990             let result = p1 / 5.0;
1991 
1992             assert_eq!(result, Point3D::new(3.0, 5.0, 7.0));
1993         }
1994 
1995         #[test]
test_div_assign_scalar()1996         pub fn test_div_assign_scalar() {
1997             let mut p1: Point3D<f32> = Point3D::new(15.0, 25.0, 35.0);
1998 
1999             p1 /= 5.0;
2000 
2001             assert_eq!(p1, Point3D::new(3.0, 5.0, 7.0));
2002         }
2003 
2004         #[test]
test_div_scale()2005         pub fn test_div_scale() {
2006             let p1 = Point3DCm::new(0.1, 0.2, 0.3);
2007             let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
2008 
2009             let result = p1 / cm_per_mm;
2010 
2011             assert_eq!(result, Point3DMm::new(1.0, 2.0, 3.0));
2012         }
2013 
2014         #[test]
test_div_assign_scale()2015         pub fn test_div_assign_scale() {
2016             let mut p1 = Point3DMm::new(0.1, 0.2, 0.3);
2017             let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
2018 
2019             p1 /= scale;
2020 
2021             assert_eq!(p1, Point3DMm::new(1.0, 2.0, 3.0));
2022         }
2023     }
2024 }
2025