1use super::UnknownUnit;
11use crate::approxeq::ApproxEq;
12use crate::approxord::{max, min};
13use crate::length::Length;
14use crate::num::*;
15use crate::scale::Scale;
16use crate::size::{Size2D, Size3D};
17use crate::vector::{vec2, vec3, Vector2D, Vector3D};
18use core::cmp::{Eq, PartialEq};
19use core::fmt;
20use core::hash::Hash;
21use core::marker::PhantomData;
22use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
23#[cfg(feature = "mint")]
24use mint;
25use num_traits::real::Real;
26use num_traits::{Euclid, Float, NumCast};
27#[cfg(feature = "serde")]
28use serde;
29
30#[cfg(feature = "bytemuck")]
31use bytemuck::{Pod, Zeroable};
32
33#[repr(C)]
35pub struct Point2D<T, U> {
36 pub x: T,
37 pub y: T,
38 #[doc(hidden)]
39 pub _unit: PhantomData<U>,
40}
41
42impl<T: Copy, U> Copy for Point2D<T, U> {}
43
44impl<T: Clone, U> Clone for Point2D<T, U> {
45 fn clone(&self) -> Self {
46 Point2D {
47 x: self.x.clone(),
48 y: self.y.clone(),
49 _unit: PhantomData,
50 }
51 }
52}
53
54#[cfg(feature = "serde")]
55impl<'de, T, U> serde::Deserialize<'de> for Point2D<T, U>
56where
57 T: serde::Deserialize<'de>,
58{
59 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
60 where
61 D: serde::Deserializer<'de>,
62 {
63 let (x, y) = serde::Deserialize::deserialize(deserializer)?;
64 Ok(Point2D {
65 x,
66 y,
67 _unit: PhantomData,
68 })
69 }
70}
71
72#[cfg(feature = "serde")]
73impl<T, U> serde::Serialize for Point2D<T, U>
74where
75 T: serde::Serialize,
76{
77 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
78 where
79 S: serde::Serializer,
80 {
81 (&self.x, &self.y).serialize(serializer)
82 }
83}
84
85#[cfg(feature = "arbitrary")]
86impl<'a, T, U> arbitrary::Arbitrary<'a> for Point2D<T, U>
87where
88 T: arbitrary::Arbitrary<'a>,
89{
90 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
91 let (x, y) = arbitrary::Arbitrary::arbitrary(u)?;
92 Ok(Point2D {
93 x,
94 y,
95 _unit: PhantomData,
96 })
97 }
98}
99
100#[cfg(feature = "bytemuck")]
101unsafe impl<T: Zeroable, U> Zeroable for Point2D<T, U> {}
102
103#[cfg(feature = "bytemuck")]
104unsafe impl<T: Pod, U: 'static> Pod for Point2D<T, U> {}
105
106impl<T, U> Eq for Point2D<T, U> where T: Eq {}
107
108impl<T, U> PartialEq for Point2D<T, U>
109where
110 T: PartialEq,
111{
112 fn eq(&self, other: &Self) -> bool {
113 self.x == other.x && self.y == other.y
114 }
115}
116
117impl<T, U> Hash for Point2D<T, U>
118where
119 T: Hash,
120{
121 fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
122 self.x.hash(h);
123 self.y.hash(h);
124 }
125}
126
127mint_vec!(Point2D[x, y] = Point2);
128
129impl<T: fmt::Debug, U> fmt::Debug for Point2D<T, U> {
130 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131 f.debug_tuple("").field(&self.x).field(&self.y).finish()
132 }
133}
134
135impl<T: Default, U> Default for Point2D<T, U> {
136 fn default() -> Self {
137 Point2D::new(Default::default(), Default::default())
138 }
139}
140
141impl<T, U> Point2D<T, U> {
142 #[inline]
144 pub fn origin() -> Self
145 where
146 T: Zero,
147 {
148 point2(Zero::zero(), Zero::zero())
149 }
150
151 #[inline]
153 pub fn zero() -> Self
154 where
155 T: Zero,
156 {
157 Self::origin()
158 }
159
160 #[inline]
162 pub const fn new(x: T, y: T) -> Self {
163 Point2D {
164 x,
165 y,
166 _unit: PhantomData,
167 }
168 }
169
170 #[inline]
172 pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self {
173 point2(x.0, y.0)
174 }
175
176 #[inline]
178 pub fn splat(v: T) -> Self
179 where
180 T: Clone,
181 {
182 Point2D {
183 x: v.clone(),
184 y: v,
185 _unit: PhantomData,
186 }
187 }
188
189 #[inline]
191 pub fn from_untyped(p: Point2D<T, UnknownUnit>) -> Self {
192 point2(p.x, p.y)
193 }
194
195 #[inline]
208 pub fn map<V, F: FnMut(T) -> V>(self, mut f: F) -> Point2D<V, U> {
209 point2(f(self.x), f(self.y))
210 }
211
212 #[inline]
226 pub fn zip<V, F: FnMut(T, T) -> V>(self, rhs: Self, mut f: F) -> Vector2D<V, U> {
227 vec2(f(self.x, rhs.x), f(self.y, rhs.y))
228 }
229}
230
231impl<T: Copy, U> Point2D<T, U> {
232 #[inline]
234 pub fn extend(self, z: T) -> Point3D<T, U> {
235 point3(self.x, self.y, z)
236 }
237
238 #[inline]
242 pub fn to_vector(self) -> Vector2D<T, U> {
243 Vector2D {
244 x: self.x,
245 y: self.y,
246 _unit: PhantomData,
247 }
248 }
249
250 #[inline]
263 pub fn yx(self) -> Self {
264 point2(self.y, self.x)
265 }
266
267 #[inline]
281 pub fn to_untyped(self) -> Point2D<T, UnknownUnit> {
282 point2(self.x, self.y)
283 }
284
285 #[inline]
300 pub fn cast_unit<V>(self) -> Point2D<T, V> {
301 point2(self.x, self.y)
302 }
303
304 #[inline]
317 pub fn to_array(self) -> [T; 2] {
318 [self.x, self.y]
319 }
320
321 #[inline]
334 pub fn to_tuple(self) -> (T, T) {
335 (self.x, self.y)
336 }
337
338 #[inline]
340 pub fn to_3d(self) -> Point3D<T, U>
341 where
342 T: Zero,
343 {
344 point3(self.x, self.y, Zero::zero())
345 }
346
347 #[inline]
358 #[must_use]
359 pub fn round(self) -> Self
360 where
361 T: Round,
362 {
363 point2(self.x.round(), self.y.round())
364 }
365
366 #[inline]
377 #[must_use]
378 pub fn ceil(self) -> Self
379 where
380 T: Ceil,
381 {
382 point2(self.x.ceil(), self.y.ceil())
383 }
384
385 #[inline]
396 #[must_use]
397 pub fn floor(self) -> Self
398 where
399 T: Floor,
400 {
401 point2(self.x.floor(), self.y.floor())
402 }
403
404 #[inline]
422 pub fn lerp(self, other: Self, t: T) -> Self
423 where
424 T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
425 {
426 let one_t = T::one() - t;
427 point2(one_t * self.x + t * other.x, one_t * self.y + t * other.y)
428 }
429}
430
431impl<T: PartialOrd, U> Point2D<T, U> {
432 #[inline]
433 pub fn min(self, other: Self) -> Self {
434 point2(min(self.x, other.x), min(self.y, other.y))
435 }
436
437 #[inline]
438 pub fn max(self, other: Self) -> Self {
439 point2(max(self.x, other.x), max(self.y, other.y))
440 }
441
442 #[inline]
447 pub fn clamp(self, start: Self, end: Self) -> Self
448 where
449 T: Copy,
450 {
451 self.max(start).min(end)
452 }
453}
454
455impl<T: NumCast + Copy, U> Point2D<T, U> {
456 #[inline]
462 pub fn cast<NewT: NumCast>(self) -> Point2D<NewT, U> {
463 self.try_cast().unwrap()
464 }
465
466 pub fn try_cast<NewT: NumCast>(self) -> Option<Point2D<NewT, U>> {
472 match (NumCast::from(self.x), NumCast::from(self.y)) {
473 (Some(x), Some(y)) => Some(point2(x, y)),
474 _ => None,
475 }
476 }
477
478 #[inline]
482 pub fn to_f32(self) -> Point2D<f32, U> {
483 self.cast()
484 }
485
486 #[inline]
488 pub fn to_f64(self) -> Point2D<f64, U> {
489 self.cast()
490 }
491
492 #[inline]
498 pub fn to_usize(self) -> Point2D<usize, U> {
499 self.cast()
500 }
501
502 #[inline]
508 pub fn to_u32(self) -> Point2D<u32, U> {
509 self.cast()
510 }
511
512 #[inline]
518 pub fn to_i32(self) -> Point2D<i32, U> {
519 self.cast()
520 }
521
522 #[inline]
528 pub fn to_i64(self) -> Point2D<i64, U> {
529 self.cast()
530 }
531}
532
533impl<T: Float, U> Point2D<T, U> {
534 #[inline]
536 pub fn is_finite(self) -> bool {
537 self.x.is_finite() && self.y.is_finite()
538 }
539}
540
541impl<T: Copy + Add<T, Output = T>, U> Point2D<T, U> {
542 #[inline]
543 pub fn add_size(self, other: &Size2D<T, U>) -> Self {
544 point2(self.x + other.width, self.y + other.height)
545 }
546}
547
548impl<T: Real + Sub<T, Output = T>, U> Point2D<T, U> {
549 #[inline]
550 pub fn distance_to(self, other: Self) -> T {
551 (self - other).length()
552 }
553}
554
555impl<T: Neg, U> Neg for Point2D<T, U> {
556 type Output = Point2D<T::Output, U>;
557
558 #[inline]
559 fn neg(self) -> Self::Output {
560 point2(-self.x, -self.y)
561 }
562}
563
564impl<T: Add, U> Add<Size2D<T, U>> for Point2D<T, U> {
565 type Output = Point2D<T::Output, U>;
566
567 #[inline]
568 fn add(self, other: Size2D<T, U>) -> Self::Output {
569 point2(self.x + other.width, self.y + other.height)
570 }
571}
572
573impl<T: AddAssign, U> AddAssign<Size2D<T, U>> for Point2D<T, U> {
574 #[inline]
575 fn add_assign(&mut self, other: Size2D<T, U>) {
576 self.x += other.width;
577 self.y += other.height;
578 }
579}
580
581impl<T: Add, U> Add<Vector2D<T, U>> for Point2D<T, U> {
582 type Output = Point2D<T::Output, U>;
583
584 #[inline]
585 fn add(self, other: Vector2D<T, U>) -> Self::Output {
586 point2(self.x + other.x, self.y + other.y)
587 }
588}
589
590impl<T: Copy + Add<T, Output = T>, U> AddAssign<Vector2D<T, U>> for Point2D<T, U> {
591 #[inline]
592 fn add_assign(&mut self, other: Vector2D<T, U>) {
593 *self = *self + other
594 }
595}
596
597impl<T: Sub, U> Sub for Point2D<T, U> {
598 type Output = Vector2D<T::Output, U>;
599
600 #[inline]
601 fn sub(self, other: Self) -> Self::Output {
602 vec2(self.x - other.x, self.y - other.y)
603 }
604}
605
606impl<T: Sub, U> Sub<Size2D<T, U>> for Point2D<T, U> {
607 type Output = Point2D<T::Output, U>;
608
609 #[inline]
610 fn sub(self, other: Size2D<T, U>) -> Self::Output {
611 point2(self.x - other.width, self.y - other.height)
612 }
613}
614
615impl<T: SubAssign, U> SubAssign<Size2D<T, U>> for Point2D<T, U> {
616 #[inline]
617 fn sub_assign(&mut self, other: Size2D<T, U>) {
618 self.x -= other.width;
619 self.y -= other.height;
620 }
621}
622
623impl<T: Sub, U> Sub<Vector2D<T, U>> for Point2D<T, U> {
624 type Output = Point2D<T::Output, U>;
625
626 #[inline]
627 fn sub(self, other: Vector2D<T, U>) -> Self::Output {
628 point2(self.x - other.x, self.y - other.y)
629 }
630}
631
632impl<T: Copy + Sub<T, Output = T>, U> SubAssign<Vector2D<T, U>> for Point2D<T, U> {
633 #[inline]
634 fn sub_assign(&mut self, other: Vector2D<T, U>) {
635 *self = *self - other
636 }
637}
638
639impl<T: Copy + Mul, U> Mul<T> for Point2D<T, U> {
640 type Output = Point2D<T::Output, U>;
641
642 #[inline]
643 fn mul(self, scale: T) -> Self::Output {
644 point2(self.x * scale, self.y * scale)
645 }
646}
647
648impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Point2D<T, U> {
649 #[inline]
650 fn mul_assign(&mut self, scale: T) {
651 *self = *self * scale
652 }
653}
654
655impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Point2D<T, U1> {
656 type Output = Point2D<T::Output, U2>;
657
658 #[inline]
659 fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
660 point2(self.x * scale.0, self.y * scale.0)
661 }
662}
663
664impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Point2D<T, U> {
665 #[inline]
666 fn mul_assign(&mut self, scale: Scale<T, U, U>) {
667 self.x *= scale.0;
668 self.y *= scale.0;
669 }
670}
671
672impl<T: Copy + Div, U> Div<T> for Point2D<T, U> {
673 type Output = Point2D<T::Output, U>;
674
675 #[inline]
676 fn div(self, scale: T) -> Self::Output {
677 point2(self.x / scale, self.y / scale)
678 }
679}
680
681impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Point2D<T, U> {
682 #[inline]
683 fn div_assign(&mut self, scale: T) {
684 *self = *self / scale
685 }
686}
687
688impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Point2D<T, U2> {
689 type Output = Point2D<T::Output, U1>;
690
691 #[inline]
692 fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
693 point2(self.x / scale.0, self.y / scale.0)
694 }
695}
696
697impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Point2D<T, U> {
698 #[inline]
699 fn div_assign(&mut self, scale: Scale<T, U, U>) {
700 self.x /= scale.0;
701 self.y /= scale.0;
702 }
703}
704
705impl<T: Zero, U> Zero for Point2D<T, U> {
706 #[inline]
707 fn zero() -> Self {
708 Self::origin()
709 }
710}
711
712impl<T: Round, U> Round for Point2D<T, U> {
713 #[inline]
715 fn round(self) -> Self {
716 self.round()
717 }
718}
719
720impl<T: Ceil, U> Ceil for Point2D<T, U> {
721 #[inline]
723 fn ceil(self) -> Self {
724 self.ceil()
725 }
726}
727
728impl<T: Floor, U> Floor for Point2D<T, U> {
729 #[inline]
731 fn floor(self) -> Self {
732 self.floor()
733 }
734}
735
736impl<T: ApproxEq<T>, U> ApproxEq<Point2D<T, U>> for Point2D<T, U> {
737 #[inline]
738 fn approx_epsilon() -> Self {
739 point2(T::approx_epsilon(), T::approx_epsilon())
740 }
741
742 #[inline]
743 fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
744 self.x.approx_eq_eps(&other.x, &eps.x) && self.y.approx_eq_eps(&other.y, &eps.y)
745 }
746}
747
748impl<T: Euclid, U> Point2D<T, U> {
749 #[inline]
765 pub fn rem_euclid(&self, other: &Size2D<T, U>) -> Self {
766 point2(
767 self.x.rem_euclid(&other.width),
768 self.y.rem_euclid(&other.height),
769 )
770 }
771
772 #[inline]
788 pub fn div_euclid(&self, other: &Size2D<T, U>) -> Self {
789 point2(
790 self.x.div_euclid(&other.width),
791 self.y.div_euclid(&other.height),
792 )
793 }
794}
795
796impl<T, U> From<Point2D<T, U>> for [T; 2] {
797 fn from(p: Point2D<T, U>) -> Self {
798 [p.x, p.y]
799 }
800}
801
802impl<T, U> From<[T; 2]> for Point2D<T, U> {
803 fn from([x, y]: [T; 2]) -> Self {
804 point2(x, y)
805 }
806}
807
808impl<T, U> From<Point2D<T, U>> for (T, T) {
809 fn from(p: Point2D<T, U>) -> Self {
810 (p.x, p.y)
811 }
812}
813
814impl<T, U> From<(T, T)> for Point2D<T, U> {
815 fn from(tuple: (T, T)) -> Self {
816 point2(tuple.0, tuple.1)
817 }
818}
819
820#[repr(C)]
822pub struct Point3D<T, U> {
823 pub x: T,
824 pub y: T,
825 pub z: T,
826 #[doc(hidden)]
827 pub _unit: PhantomData<U>,
828}
829
830mint_vec!(Point3D[x, y, z] = Point3);
831
832impl<T: Copy, U> Copy for Point3D<T, U> {}
833
834impl<T: Clone, U> Clone for Point3D<T, U> {
835 fn clone(&self) -> Self {
836 Point3D {
837 x: self.x.clone(),
838 y: self.y.clone(),
839 z: self.z.clone(),
840 _unit: PhantomData,
841 }
842 }
843}
844
845#[cfg(feature = "serde")]
846impl<'de, T, U> serde::Deserialize<'de> for Point3D<T, U>
847where
848 T: serde::Deserialize<'de>,
849{
850 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
851 where
852 D: serde::Deserializer<'de>,
853 {
854 let (x, y, z) = serde::Deserialize::deserialize(deserializer)?;
855 Ok(Point3D {
856 x,
857 y,
858 z,
859 _unit: PhantomData,
860 })
861 }
862}
863
864#[cfg(feature = "serde")]
865impl<T, U> serde::Serialize for Point3D<T, U>
866where
867 T: serde::Serialize,
868{
869 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
870 where
871 S: serde::Serializer,
872 {
873 (&self.x, &self.y, &self.z).serialize(serializer)
874 }
875}
876
877#[cfg(feature = "arbitrary")]
878impl<'a, T, U> arbitrary::Arbitrary<'a> for Point3D<T, U>
879where
880 T: arbitrary::Arbitrary<'a>,
881{
882 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
883 let (x, y, z) = arbitrary::Arbitrary::arbitrary(u)?;
884 Ok(Point3D {
885 x,
886 y,
887 z,
888 _unit: PhantomData,
889 })
890 }
891}
892
893#[cfg(feature = "bytemuck")]
894unsafe impl<T: Zeroable, U> Zeroable for Point3D<T, U> {}
895
896#[cfg(feature = "bytemuck")]
897unsafe impl<T: Pod, U: 'static> Pod for Point3D<T, U> {}
898
899impl<T, U> Eq for Point3D<T, U> where T: Eq {}
900
901impl<T, U> PartialEq for Point3D<T, U>
902where
903 T: PartialEq,
904{
905 fn eq(&self, other: &Self) -> bool {
906 self.x == other.x && self.y == other.y && self.z == other.z
907 }
908}
909
910impl<T, U> Hash for Point3D<T, U>
911where
912 T: Hash,
913{
914 fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
915 self.x.hash(h);
916 self.y.hash(h);
917 self.z.hash(h);
918 }
919}
920
921impl<T: fmt::Debug, U> fmt::Debug for Point3D<T, U> {
922 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
923 f.debug_tuple("")
924 .field(&self.x)
925 .field(&self.y)
926 .field(&self.z)
927 .finish()
928 }
929}
930
931impl<T: Default, U> Default for Point3D<T, U> {
932 fn default() -> Self {
933 Point3D::new(Default::default(), Default::default(), Default::default())
934 }
935}
936
937impl<T, U> Point3D<T, U> {
938 #[inline]
940 pub fn origin() -> Self
941 where
942 T: Zero,
943 {
944 point3(Zero::zero(), Zero::zero(), Zero::zero())
945 }
946
947 #[inline]
949 pub fn zero() -> Self
950 where
951 T: Zero,
952 {
953 Self::origin()
954 }
955
956 #[inline]
958 pub const fn new(x: T, y: T, z: T) -> Self {
959 Point3D {
960 x,
961 y,
962 z,
963 _unit: PhantomData,
964 }
965 }
966
967 #[inline]
969 pub fn from_lengths(x: Length<T, U>, y: Length<T, U>, z: Length<T, U>) -> Self {
970 point3(x.0, y.0, z.0)
971 }
972
973 #[inline]
975 pub fn splat(v: T) -> Self
976 where
977 T: Clone,
978 {
979 Point3D {
980 x: v.clone(),
981 y: v.clone(),
982 z: v,
983 _unit: PhantomData,
984 }
985 }
986
987 #[inline]
989 pub fn from_untyped(p: Point3D<T, UnknownUnit>) -> Self {
990 point3(p.x, p.y, p.z)
991 }
992
993 #[inline]
1006 pub fn map<V, F: FnMut(T) -> V>(self, mut f: F) -> Point3D<V, U> {
1007 point3(f(self.x), f(self.y), f(self.z))
1008 }
1009
1010 #[inline]
1024 pub fn zip<V, F: FnMut(T, T) -> V>(self, rhs: Self, mut f: F) -> Vector3D<V, U> {
1025 vec3(f(self.x, rhs.x), f(self.y, rhs.y), f(self.z, rhs.z))
1026 }
1027}
1028
1029impl<T: Copy, U> Point3D<T, U> {
1030 #[inline]
1034 pub fn to_vector(self) -> Vector3D<T, U> {
1035 Vector3D {
1036 x: self.x,
1037 y: self.y,
1038 z: self.z,
1039 _unit: PhantomData,
1040 }
1041 }
1042
1043 #[inline]
1045 pub fn xy(self) -> Point2D<T, U> {
1046 point2(self.x, self.y)
1047 }
1048
1049 #[inline]
1051 pub fn xz(self) -> Point2D<T, U> {
1052 point2(self.x, self.z)
1053 }
1054
1055 #[inline]
1057 pub fn yz(self) -> Point2D<T, U> {
1058 point2(self.y, self.z)
1059 }
1060
1061 #[inline]
1074 pub fn to_array(self) -> [T; 3] {
1075 [self.x, self.y, self.z]
1076 }
1077
1078 #[inline]
1079 pub fn to_array_4d(self) -> [T; 4]
1080 where
1081 T: One,
1082 {
1083 [self.x, self.y, self.z, One::one()]
1084 }
1085
1086 #[inline]
1099 pub fn to_tuple(self) -> (T, T, T) {
1100 (self.x, self.y, self.z)
1101 }
1102
1103 #[inline]
1104 pub fn to_tuple_4d(self) -> (T, T, T, T)
1105 where
1106 T: One,
1107 {
1108 (self.x, self.y, self.z, One::one())
1109 }
1110
1111 #[inline]
1126 pub fn to_untyped(self) -> Point3D<T, UnknownUnit> {
1127 point3(self.x, self.y, self.z)
1128 }
1129
1130 #[inline]
1146 pub fn cast_unit<V>(self) -> Point3D<T, V> {
1147 point3(self.x, self.y, self.z)
1148 }
1149
1150 #[inline]
1152 pub fn to_2d(self) -> Point2D<T, U> {
1153 self.xy()
1154 }
1155
1156 #[inline]
1167 #[must_use]
1168 pub fn round(self) -> Self
1169 where
1170 T: Round,
1171 {
1172 point3(self.x.round(), self.y.round(), self.z.round())
1173 }
1174
1175 #[inline]
1186 #[must_use]
1187 pub fn ceil(self) -> Self
1188 where
1189 T: Ceil,
1190 {
1191 point3(self.x.ceil(), self.y.ceil(), self.z.ceil())
1192 }
1193
1194 #[inline]
1205 #[must_use]
1206 pub fn floor(self) -> Self
1207 where
1208 T: Floor,
1209 {
1210 point3(self.x.floor(), self.y.floor(), self.z.floor())
1211 }
1212
1213 #[inline]
1231 pub fn lerp(self, other: Self, t: T) -> Self
1232 where
1233 T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
1234 {
1235 let one_t = T::one() - t;
1236 point3(
1237 one_t * self.x + t * other.x,
1238 one_t * self.y + t * other.y,
1239 one_t * self.z + t * other.z,
1240 )
1241 }
1242}
1243
1244impl<T: PartialOrd, U> Point3D<T, U> {
1245 #[inline]
1246 pub fn min(self, other: Self) -> Self {
1247 point3(
1248 min(self.x, other.x),
1249 min(self.y, other.y),
1250 min(self.z, other.z),
1251 )
1252 }
1253
1254 #[inline]
1255 pub fn max(self, other: Self) -> Self {
1256 point3(
1257 max(self.x, other.x),
1258 max(self.y, other.y),
1259 max(self.z, other.z),
1260 )
1261 }
1262
1263 #[inline]
1268 pub fn clamp(self, start: Self, end: Self) -> Self
1269 where
1270 T: Copy,
1271 {
1272 self.max(start).min(end)
1273 }
1274}
1275
1276impl<T: NumCast + Copy, U> Point3D<T, U> {
1277 #[inline]
1283 pub fn cast<NewT: NumCast>(self) -> Point3D<NewT, U> {
1284 self.try_cast().unwrap()
1285 }
1286
1287 pub fn try_cast<NewT: NumCast>(self) -> Option<Point3D<NewT, U>> {
1293 match (
1294 NumCast::from(self.x),
1295 NumCast::from(self.y),
1296 NumCast::from(self.z),
1297 ) {
1298 (Some(x), Some(y), Some(z)) => Some(point3(x, y, z)),
1299 _ => None,
1300 }
1301 }
1302
1303 #[inline]
1307 pub fn to_f32(self) -> Point3D<f32, U> {
1308 self.cast()
1309 }
1310
1311 #[inline]
1313 pub fn to_f64(self) -> Point3D<f64, U> {
1314 self.cast()
1315 }
1316
1317 #[inline]
1323 pub fn to_usize(self) -> Point3D<usize, U> {
1324 self.cast()
1325 }
1326
1327 #[inline]
1333 pub fn to_u32(self) -> Point3D<u32, U> {
1334 self.cast()
1335 }
1336
1337 #[inline]
1343 pub fn to_i32(self) -> Point3D<i32, U> {
1344 self.cast()
1345 }
1346
1347 #[inline]
1353 pub fn to_i64(self) -> Point3D<i64, U> {
1354 self.cast()
1355 }
1356}
1357
1358impl<T: Float, U> Point3D<T, U> {
1359 #[inline]
1361 pub fn is_finite(self) -> bool {
1362 self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
1363 }
1364}
1365
1366impl<T: Copy + Add<T, Output = T>, U> Point3D<T, U> {
1367 #[inline]
1368 pub fn add_size(self, other: Size3D<T, U>) -> Self {
1369 point3(
1370 self.x + other.width,
1371 self.y + other.height,
1372 self.z + other.depth,
1373 )
1374 }
1375}
1376
1377impl<T: Real + Sub<T, Output = T>, U> Point3D<T, U> {
1378 #[inline]
1379 pub fn distance_to(self, other: Self) -> T {
1380 (self - other).length()
1381 }
1382}
1383
1384impl<T: Neg, U> Neg for Point3D<T, U> {
1385 type Output = Point3D<T::Output, U>;
1386
1387 #[inline]
1388 fn neg(self) -> Self::Output {
1389 point3(-self.x, -self.y, -self.z)
1390 }
1391}
1392
1393impl<T: Add, U> Add<Size3D<T, U>> for Point3D<T, U> {
1394 type Output = Point3D<T::Output, U>;
1395
1396 #[inline]
1397 fn add(self, other: Size3D<T, U>) -> Self::Output {
1398 point3(
1399 self.x + other.width,
1400 self.y + other.height,
1401 self.z + other.depth,
1402 )
1403 }
1404}
1405
1406impl<T: AddAssign, U> AddAssign<Size3D<T, U>> for Point3D<T, U> {
1407 #[inline]
1408 fn add_assign(&mut self, other: Size3D<T, U>) {
1409 self.x += other.width;
1410 self.y += other.height;
1411 self.z += other.depth;
1412 }
1413}
1414
1415impl<T: Add, U> Add<Vector3D<T, U>> for Point3D<T, U> {
1416 type Output = Point3D<T::Output, U>;
1417
1418 #[inline]
1419 fn add(self, other: Vector3D<T, U>) -> Self::Output {
1420 point3(self.x + other.x, self.y + other.y, self.z + other.z)
1421 }
1422}
1423
1424impl<T: Copy + Add<T, Output = T>, U> AddAssign<Vector3D<T, U>> for Point3D<T, U> {
1425 #[inline]
1426 fn add_assign(&mut self, other: Vector3D<T, U>) {
1427 *self = *self + other
1428 }
1429}
1430
1431impl<T: Sub, U> Sub for Point3D<T, U> {
1432 type Output = Vector3D<T::Output, U>;
1433
1434 #[inline]
1435 fn sub(self, other: Self) -> Self::Output {
1436 vec3(self.x - other.x, self.y - other.y, self.z - other.z)
1437 }
1438}
1439
1440impl<T: Sub, U> Sub<Size3D<T, U>> for Point3D<T, U> {
1441 type Output = Point3D<T::Output, U>;
1442
1443 #[inline]
1444 fn sub(self, other: Size3D<T, U>) -> Self::Output {
1445 point3(
1446 self.x - other.width,
1447 self.y - other.height,
1448 self.z - other.depth,
1449 )
1450 }
1451}
1452
1453impl<T: SubAssign, U> SubAssign<Size3D<T, U>> for Point3D<T, U> {
1454 #[inline]
1455 fn sub_assign(&mut self, other: Size3D<T, U>) {
1456 self.x -= other.width;
1457 self.y -= other.height;
1458 self.z -= other.depth;
1459 }
1460}
1461
1462impl<T: Sub, U> Sub<Vector3D<T, U>> for Point3D<T, U> {
1463 type Output = Point3D<T::Output, U>;
1464
1465 #[inline]
1466 fn sub(self, other: Vector3D<T, U>) -> Self::Output {
1467 point3(self.x - other.x, self.y - other.y, self.z - other.z)
1468 }
1469}
1470
1471impl<T: Copy + Sub<T, Output = T>, U> SubAssign<Vector3D<T, U>> for Point3D<T, U> {
1472 #[inline]
1473 fn sub_assign(&mut self, other: Vector3D<T, U>) {
1474 *self = *self - other
1475 }
1476}
1477
1478impl<T: Copy + Mul, U> Mul<T> for Point3D<T, U> {
1479 type Output = Point3D<T::Output, U>;
1480
1481 #[inline]
1482 fn mul(self, scale: T) -> Self::Output {
1483 point3(self.x * scale, self.y * scale, self.z * scale)
1484 }
1485}
1486
1487impl<T: Copy + MulAssign, U> MulAssign<T> for Point3D<T, U> {
1488 #[inline]
1489 fn mul_assign(&mut self, scale: T) {
1490 self.x *= scale;
1491 self.y *= scale;
1492 self.z *= scale;
1493 }
1494}
1495
1496impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Point3D<T, U1> {
1497 type Output = Point3D<T::Output, U2>;
1498
1499 #[inline]
1500 fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
1501 point3(self.x * scale.0, self.y * scale.0, self.z * scale.0)
1502 }
1503}
1504
1505impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Point3D<T, U> {
1506 #[inline]
1507 fn mul_assign(&mut self, scale: Scale<T, U, U>) {
1508 *self *= scale.0;
1509 }
1510}
1511
1512impl<T: Copy + Div, U> Div<T> for Point3D<T, U> {
1513 type Output = Point3D<T::Output, U>;
1514
1515 #[inline]
1516 fn div(self, scale: T) -> Self::Output {
1517 point3(self.x / scale, self.y / scale, self.z / scale)
1518 }
1519}
1520
1521impl<T: Copy + DivAssign, U> DivAssign<T> for Point3D<T, U> {
1522 #[inline]
1523 fn div_assign(&mut self, scale: T) {
1524 self.x /= scale;
1525 self.y /= scale;
1526 self.z /= scale;
1527 }
1528}
1529
1530impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Point3D<T, U2> {
1531 type Output = Point3D<T::Output, U1>;
1532
1533 #[inline]
1534 fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
1535 point3(self.x / scale.0, self.y / scale.0, self.z / scale.0)
1536 }
1537}
1538
1539impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Point3D<T, U> {
1540 #[inline]
1541 fn div_assign(&mut self, scale: Scale<T, U, U>) {
1542 *self /= scale.0;
1543 }
1544}
1545
1546impl<T: Zero, U> Zero for Point3D<T, U> {
1547 #[inline]
1548 fn zero() -> Self {
1549 Self::origin()
1550 }
1551}
1552
1553impl<T: Round, U> Round for Point3D<T, U> {
1554 #[inline]
1556 fn round(self) -> Self {
1557 self.round()
1558 }
1559}
1560
1561impl<T: Ceil, U> Ceil for Point3D<T, U> {
1562 #[inline]
1564 fn ceil(self) -> Self {
1565 self.ceil()
1566 }
1567}
1568
1569impl<T: Floor, U> Floor for Point3D<T, U> {
1570 #[inline]
1572 fn floor(self) -> Self {
1573 self.floor()
1574 }
1575}
1576
1577impl<T: ApproxEq<T>, U> ApproxEq<Point3D<T, U>> for Point3D<T, U> {
1578 #[inline]
1579 fn approx_epsilon() -> Self {
1580 point3(
1581 T::approx_epsilon(),
1582 T::approx_epsilon(),
1583 T::approx_epsilon(),
1584 )
1585 }
1586
1587 #[inline]
1588 fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
1589 self.x.approx_eq_eps(&other.x, &eps.x)
1590 && self.y.approx_eq_eps(&other.y, &eps.y)
1591 && self.z.approx_eq_eps(&other.z, &eps.z)
1592 }
1593}
1594
1595impl<T: Euclid, U> Point3D<T, U> {
1596 #[inline]
1612 pub fn rem_euclid(&self, other: &Size3D<T, U>) -> Self {
1613 point3(
1614 self.x.rem_euclid(&other.width),
1615 self.y.rem_euclid(&other.height),
1616 self.z.rem_euclid(&other.depth),
1617 )
1618 }
1619
1620 #[inline]
1636 pub fn div_euclid(&self, other: &Size3D<T, U>) -> Self {
1637 point3(
1638 self.x.div_euclid(&other.width),
1639 self.y.div_euclid(&other.height),
1640 self.z.div_euclid(&other.depth),
1641 )
1642 }
1643}
1644
1645impl<T, U> From<Point3D<T, U>> for [T; 3] {
1646 fn from(p: Point3D<T, U>) -> Self {
1647 [p.x, p.y, p.z]
1648 }
1649}
1650
1651impl<T, U> From<[T; 3]> for Point3D<T, U> {
1652 fn from([x, y, z]: [T; 3]) -> Self {
1653 point3(x, y, z)
1654 }
1655}
1656
1657impl<T, U> From<Point3D<T, U>> for (T, T, T) {
1658 fn from(p: Point3D<T, U>) -> Self {
1659 (p.x, p.y, p.z)
1660 }
1661}
1662
1663impl<T, U> From<(T, T, T)> for Point3D<T, U> {
1664 fn from(tuple: (T, T, T)) -> Self {
1665 point3(tuple.0, tuple.1, tuple.2)
1666 }
1667}
1668
1669#[inline]
1671pub const fn point2<T, U>(x: T, y: T) -> Point2D<T, U> {
1672 Point2D {
1673 x,
1674 y,
1675 _unit: PhantomData,
1676 }
1677}
1678
1679#[inline]
1681pub const fn point3<T, U>(x: T, y: T, z: T) -> Point3D<T, U> {
1682 Point3D {
1683 x,
1684 y,
1685 z,
1686 _unit: PhantomData,
1687 }
1688}
1689
1690#[cfg(test)]
1691mod point2d {
1692 use crate::default::Point2D;
1693 use crate::point2;
1694
1695 #[cfg(feature = "mint")]
1696 use mint;
1697
1698 #[test]
1699 pub fn test_min() {
1700 let p1 = Point2D::new(1.0, 3.0);
1701 let p2 = Point2D::new(2.0, 2.0);
1702
1703 let result = p1.min(p2);
1704
1705 assert_eq!(result, Point2D::new(1.0, 2.0));
1706 }
1707
1708 #[test]
1709 pub fn test_max() {
1710 let p1 = Point2D::new(1.0, 3.0);
1711 let p2 = Point2D::new(2.0, 2.0);
1712
1713 let result = p1.max(p2);
1714
1715 assert_eq!(result, Point2D::new(2.0, 3.0));
1716 }
1717
1718 #[cfg(feature = "mint")]
1719 #[test]
1720 pub fn test_mint() {
1721 let p1 = Point2D::new(1.0, 3.0);
1722 let pm: mint::Point2<_> = p1.into();
1723 let p2 = Point2D::from(pm);
1724
1725 assert_eq!(p1, p2);
1726 }
1727
1728 #[test]
1729 pub fn test_conv_vector() {
1730 for i in 0..100 {
1731 let x = i as f32 * 0.012345;
1733 let y = i as f32 * 0.987654;
1734 let p: Point2D<f32> = point2(x, y);
1735 assert_eq!(p.to_vector().to_point(), p);
1736 }
1737 }
1738
1739 #[test]
1740 pub fn test_swizzling() {
1741 let p: Point2D<i32> = point2(1, 2);
1742 assert_eq!(p.yx(), point2(2, 1));
1743 }
1744
1745 #[test]
1746 pub fn test_distance_to() {
1747 let p1 = Point2D::new(1.0, 2.0);
1748 let p2 = Point2D::new(2.0, 2.0);
1749
1750 assert_eq!(p1.distance_to(p2), 1.0);
1751
1752 let p1 = Point2D::new(1.0, 2.0);
1753 let p2 = Point2D::new(1.0, 4.0);
1754
1755 assert_eq!(p1.distance_to(p2), 2.0);
1756 }
1757
1758 mod ops {
1759 use crate::default::Point2D;
1760 use crate::scale::Scale;
1761 use crate::{size2, vec2, Vector2D};
1762
1763 pub enum Mm {}
1764 pub enum Cm {}
1765
1766 pub type Point2DMm<T> = crate::Point2D<T, Mm>;
1767 pub type Point2DCm<T> = crate::Point2D<T, Cm>;
1768
1769 #[test]
1770 pub fn test_neg() {
1771 assert_eq!(-Point2D::new(1.0, 2.0), Point2D::new(-1.0, -2.0));
1772 assert_eq!(-Point2D::new(0.0, 0.0), Point2D::new(-0.0, -0.0));
1773 assert_eq!(-Point2D::new(-1.0, -2.0), Point2D::new(1.0, 2.0));
1774 }
1775
1776 #[test]
1777 pub fn test_add_size() {
1778 let p1 = Point2DMm::new(1.0, 2.0);
1779 let p2 = size2(3.0, 4.0);
1780
1781 let result = p1 + p2;
1782
1783 assert_eq!(result, Point2DMm::new(4.0, 6.0));
1784 }
1785
1786 #[test]
1787 pub fn test_add_assign_size() {
1788 let mut p1 = Point2DMm::new(1.0, 2.0);
1789
1790 p1 += size2(3.0, 4.0);
1791
1792 assert_eq!(p1, Point2DMm::new(4.0, 6.0));
1793 }
1794
1795 #[test]
1796 pub fn test_add_vec() {
1797 let p1 = Point2DMm::new(1.0, 2.0);
1798 let p2 = vec2(3.0, 4.0);
1799
1800 let result = p1 + p2;
1801
1802 assert_eq!(result, Point2DMm::new(4.0, 6.0));
1803 }
1804
1805 #[test]
1806 pub fn test_add_assign_vec() {
1807 let mut p1 = Point2DMm::new(1.0, 2.0);
1808
1809 p1 += vec2(3.0, 4.0);
1810
1811 assert_eq!(p1, Point2DMm::new(4.0, 6.0));
1812 }
1813
1814 #[test]
1815 pub fn test_sub() {
1816 let p1 = Point2DMm::new(1.0, 2.0);
1817 let p2 = Point2DMm::new(3.0, 4.0);
1818
1819 let result = p1 - p2;
1820
1821 assert_eq!(result, Vector2D::<_, Mm>::new(-2.0, -2.0));
1822 }
1823
1824 #[test]
1825 pub fn test_sub_size() {
1826 let p1 = Point2DMm::new(1.0, 2.0);
1827 let p2 = size2(3.0, 4.0);
1828
1829 let result = p1 - p2;
1830
1831 assert_eq!(result, Point2DMm::new(-2.0, -2.0));
1832 }
1833
1834 #[test]
1835 pub fn test_sub_assign_size() {
1836 let mut p1 = Point2DMm::new(1.0, 2.0);
1837
1838 p1 -= size2(3.0, 4.0);
1839
1840 assert_eq!(p1, Point2DMm::new(-2.0, -2.0));
1841 }
1842
1843 #[test]
1844 pub fn test_sub_vec() {
1845 let p1 = Point2DMm::new(1.0, 2.0);
1846 let p2 = vec2(3.0, 4.0);
1847
1848 let result = p1 - p2;
1849
1850 assert_eq!(result, Point2DMm::new(-2.0, -2.0));
1851 }
1852
1853 #[test]
1854 pub fn test_sub_assign_vec() {
1855 let mut p1 = Point2DMm::new(1.0, 2.0);
1856
1857 p1 -= vec2(3.0, 4.0);
1858
1859 assert_eq!(p1, Point2DMm::new(-2.0, -2.0));
1860 }
1861
1862 #[test]
1863 pub fn test_mul_scalar() {
1864 let p1: Point2D<f32> = Point2D::new(3.0, 5.0);
1865
1866 let result = p1 * 5.0;
1867
1868 assert_eq!(result, Point2D::new(15.0, 25.0));
1869 }
1870
1871 #[test]
1872 pub fn test_mul_assign_scalar() {
1873 let mut p1 = Point2D::new(3.0, 5.0);
1874
1875 p1 *= 5.0;
1876
1877 assert_eq!(p1, Point2D::new(15.0, 25.0));
1878 }
1879
1880 #[test]
1881 pub fn test_mul_scale() {
1882 let p1 = Point2DMm::new(1.0, 2.0);
1883 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
1884
1885 let result = p1 * cm_per_mm;
1886
1887 assert_eq!(result, Point2DCm::new(0.1, 0.2));
1888 }
1889
1890 #[test]
1891 pub fn test_mul_assign_scale() {
1892 let mut p1 = Point2DMm::new(1.0, 2.0);
1893 let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
1894
1895 p1 *= scale;
1896
1897 assert_eq!(p1, Point2DMm::new(0.1, 0.2));
1898 }
1899
1900 #[test]
1901 pub fn test_div_scalar() {
1902 let p1: Point2D<f32> = Point2D::new(15.0, 25.0);
1903
1904 let result = p1 / 5.0;
1905
1906 assert_eq!(result, Point2D::new(3.0, 5.0));
1907 }
1908
1909 #[test]
1910 pub fn test_div_assign_scalar() {
1911 let mut p1: Point2D<f32> = Point2D::new(15.0, 25.0);
1912
1913 p1 /= 5.0;
1914
1915 assert_eq!(p1, Point2D::new(3.0, 5.0));
1916 }
1917
1918 #[test]
1919 pub fn test_div_scale() {
1920 let p1 = Point2DCm::new(0.1, 0.2);
1921 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
1922
1923 let result = p1 / cm_per_mm;
1924
1925 assert_eq!(result, Point2DMm::new(1.0, 2.0));
1926 }
1927
1928 #[test]
1929 pub fn test_div_assign_scale() {
1930 let mut p1 = Point2DMm::new(0.1, 0.2);
1931 let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
1932
1933 p1 /= scale;
1934
1935 assert_eq!(p1, Point2DMm::new(1.0, 2.0));
1936 }
1937
1938 #[test]
1939 pub fn test_point_debug_formatting() {
1940 let n = 1.23456789;
1941 let p1 = Point2D::new(n, -n);
1942 let should_be = format!("({:.4}, {:.4})", n, -n);
1943
1944 let got = format!("{:.4?}", p1);
1945
1946 assert_eq!(got, should_be);
1947 }
1948 }
1949
1950 mod euclid {
1951 use crate::default::{Point2D, Size2D};
1952 use crate::point2;
1953
1954 #[test]
1955 pub fn test_rem_euclid() {
1956 let p = Point2D::new(7.0, -7.0);
1957 let s = Size2D::new(4.0, -4.0);
1958
1959 assert_eq!(p.rem_euclid(&s), point2(3.0, 1.0));
1960 assert_eq!((-p).rem_euclid(&s), point2(1.0, 3.0));
1961 assert_eq!(p.rem_euclid(&-s), point2(3.0, 1.0));
1962 }
1963
1964 #[test]
1965 pub fn test_div_euclid() {
1966 let p = Point2D::new(7.0, -7.0);
1967 let s = Size2D::new(4.0, -4.0);
1968
1969 assert_eq!(p.div_euclid(&s), point2(1.0, 2.0));
1970 assert_eq!((-p).div_euclid(&s), point2(-2.0, -1.0));
1971 assert_eq!(p.div_euclid(&-s), point2(-1.0, -2.0));
1972 }
1973 }
1974}
1975
1976#[cfg(test)]
1977mod point3d {
1978 use crate::default;
1979 use crate::default::Point3D;
1980 use crate::{point2, point3};
1981 #[cfg(feature = "mint")]
1982 use mint;
1983
1984 #[test]
1985 pub fn test_min() {
1986 let p1 = Point3D::new(1.0, 3.0, 5.0);
1987 let p2 = Point3D::new(2.0, 2.0, -1.0);
1988
1989 let result = p1.min(p2);
1990
1991 assert_eq!(result, Point3D::new(1.0, 2.0, -1.0));
1992 }
1993
1994 #[test]
1995 pub fn test_max() {
1996 let p1 = Point3D::new(1.0, 3.0, 5.0);
1997 let p2 = Point3D::new(2.0, 2.0, -1.0);
1998
1999 let result = p1.max(p2);
2000
2001 assert_eq!(result, Point3D::new(2.0, 3.0, 5.0));
2002 }
2003
2004 #[test]
2005 pub fn test_conv_vector() {
2006 use crate::point3;
2007 for i in 0..100 {
2008 let x = i as f32 * 0.012345;
2010 let y = i as f32 * 0.987654;
2011 let z = x * y;
2012 let p: Point3D<f32> = point3(x, y, z);
2013 assert_eq!(p.to_vector().to_point(), p);
2014 }
2015 }
2016
2017 #[test]
2018 pub fn test_swizzling() {
2019 let p: default::Point3D<i32> = point3(1, 2, 3);
2020 assert_eq!(p.xy(), point2(1, 2));
2021 assert_eq!(p.xz(), point2(1, 3));
2022 assert_eq!(p.yz(), point2(2, 3));
2023 }
2024
2025 #[test]
2026 pub fn test_distance_to() {
2027 let p1 = Point3D::new(1.0, 2.0, 3.0);
2028 let p2 = Point3D::new(2.0, 2.0, 3.0);
2029
2030 assert_eq!(p1.distance_to(p2), 1.0);
2031
2032 let p1 = Point3D::new(1.0, 2.0, 3.0);
2033 let p2 = Point3D::new(1.0, 4.0, 3.0);
2034
2035 assert_eq!(p1.distance_to(p2), 2.0);
2036
2037 let p1 = Point3D::new(1.0, 2.0, 3.0);
2038 let p2 = Point3D::new(1.0, 2.0, 6.0);
2039
2040 assert_eq!(p1.distance_to(p2), 3.0);
2041 }
2042
2043 #[cfg(feature = "mint")]
2044 #[test]
2045 pub fn test_mint() {
2046 let p1 = Point3D::new(1.0, 3.0, 5.0);
2047 let pm: mint::Point3<_> = p1.into();
2048 let p2 = Point3D::from(pm);
2049
2050 assert_eq!(p1, p2);
2051 }
2052
2053 mod ops {
2054 use crate::default::Point3D;
2055 use crate::scale::Scale;
2056 use crate::{size3, vec3, Vector3D};
2057
2058 pub enum Mm {}
2059 pub enum Cm {}
2060
2061 pub type Point3DMm<T> = crate::Point3D<T, Mm>;
2062 pub type Point3DCm<T> = crate::Point3D<T, Cm>;
2063
2064 #[test]
2065 pub fn test_neg() {
2066 assert_eq!(-Point3D::new(1.0, 2.0, 3.0), Point3D::new(-1.0, -2.0, -3.0));
2067 assert_eq!(-Point3D::new(0.0, 0.0, 0.0), Point3D::new(-0.0, -0.0, -0.0));
2068 assert_eq!(-Point3D::new(-1.0, -2.0, -3.0), Point3D::new(1.0, 2.0, 3.0));
2069 }
2070
2071 #[test]
2072 pub fn test_add_size() {
2073 let p1 = Point3DMm::new(1.0, 2.0, 3.0);
2074 let p2 = size3(4.0, 5.0, 6.0);
2075
2076 let result = p1 + p2;
2077
2078 assert_eq!(result, Point3DMm::new(5.0, 7.0, 9.0));
2079 }
2080
2081 #[test]
2082 pub fn test_add_assign_size() {
2083 let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
2084
2085 p1 += size3(4.0, 5.0, 6.0);
2086
2087 assert_eq!(p1, Point3DMm::new(5.0, 7.0, 9.0));
2088 }
2089
2090 #[test]
2091 pub fn test_add_vec() {
2092 let p1 = Point3DMm::new(1.0, 2.0, 3.0);
2093 let p2 = vec3(4.0, 5.0, 6.0);
2094
2095 let result = p1 + p2;
2096
2097 assert_eq!(result, Point3DMm::new(5.0, 7.0, 9.0));
2098 }
2099
2100 #[test]
2101 pub fn test_add_assign_vec() {
2102 let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
2103
2104 p1 += vec3(4.0, 5.0, 6.0);
2105
2106 assert_eq!(p1, Point3DMm::new(5.0, 7.0, 9.0));
2107 }
2108
2109 #[test]
2110 pub fn test_sub() {
2111 let p1 = Point3DMm::new(1.0, 2.0, 3.0);
2112 let p2 = Point3DMm::new(4.0, 5.0, 6.0);
2113
2114 let result = p1 - p2;
2115
2116 assert_eq!(result, Vector3D::<_, Mm>::new(-3.0, -3.0, -3.0));
2117 }
2118
2119 #[test]
2120 pub fn test_sub_size() {
2121 let p1 = Point3DMm::new(1.0, 2.0, 3.0);
2122 let p2 = size3(4.0, 5.0, 6.0);
2123
2124 let result = p1 - p2;
2125
2126 assert_eq!(result, Point3DMm::new(-3.0, -3.0, -3.0));
2127 }
2128
2129 #[test]
2130 pub fn test_sub_assign_size() {
2131 let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
2132
2133 p1 -= size3(4.0, 5.0, 6.0);
2134
2135 assert_eq!(p1, Point3DMm::new(-3.0, -3.0, -3.0));
2136 }
2137
2138 #[test]
2139 pub fn test_sub_vec() {
2140 let p1 = Point3DMm::new(1.0, 2.0, 3.0);
2141 let p2 = vec3(4.0, 5.0, 6.0);
2142
2143 let result = p1 - p2;
2144
2145 assert_eq!(result, Point3DMm::new(-3.0, -3.0, -3.0));
2146 }
2147
2148 #[test]
2149 pub fn test_sub_assign_vec() {
2150 let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
2151
2152 p1 -= vec3(4.0, 5.0, 6.0);
2153
2154 assert_eq!(p1, Point3DMm::new(-3.0, -3.0, -3.0));
2155 }
2156
2157 #[test]
2158 pub fn test_mul_scalar() {
2159 let p1: Point3D<f32> = Point3D::new(3.0, 5.0, 7.0);
2160
2161 let result = p1 * 5.0;
2162
2163 assert_eq!(result, Point3D::new(15.0, 25.0, 35.0));
2164 }
2165
2166 #[test]
2167 pub fn test_mul_assign_scalar() {
2168 let mut p1: Point3D<f32> = Point3D::new(3.0, 5.0, 7.0);
2169
2170 p1 *= 5.0;
2171
2172 assert_eq!(p1, Point3D::new(15.0, 25.0, 35.0));
2173 }
2174
2175 #[test]
2176 pub fn test_mul_scale() {
2177 let p1 = Point3DMm::new(1.0, 2.0, 3.0);
2178 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
2179
2180 let result = p1 * cm_per_mm;
2181
2182 assert_eq!(result, Point3DCm::new(0.1, 0.2, 0.3));
2183 }
2184
2185 #[test]
2186 pub fn test_mul_assign_scale() {
2187 let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
2188 let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
2189
2190 p1 *= scale;
2191
2192 assert_eq!(p1, Point3DMm::new(0.1, 0.2, 0.3));
2193 }
2194
2195 #[test]
2196 pub fn test_div_scalar() {
2197 let p1: Point3D<f32> = Point3D::new(15.0, 25.0, 35.0);
2198
2199 let result = p1 / 5.0;
2200
2201 assert_eq!(result, Point3D::new(3.0, 5.0, 7.0));
2202 }
2203
2204 #[test]
2205 pub fn test_div_assign_scalar() {
2206 let mut p1: Point3D<f32> = Point3D::new(15.0, 25.0, 35.0);
2207
2208 p1 /= 5.0;
2209
2210 assert_eq!(p1, Point3D::new(3.0, 5.0, 7.0));
2211 }
2212
2213 #[test]
2214 pub fn test_div_scale() {
2215 let p1 = Point3DCm::new(0.1, 0.2, 0.3);
2216 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
2217
2218 let result = p1 / cm_per_mm;
2219
2220 assert_eq!(result, Point3DMm::new(1.0, 2.0, 3.0));
2221 }
2222
2223 #[test]
2224 pub fn test_div_assign_scale() {
2225 let mut p1 = Point3DMm::new(0.1, 0.2, 0.3);
2226 let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
2227
2228 p1 /= scale;
2229
2230 assert_eq!(p1, Point3DMm::new(1.0, 2.0, 3.0));
2231 }
2232 }
2233
2234 mod euclid {
2235 use crate::default::{Point3D, Size3D};
2236 use crate::point3;
2237
2238 #[test]
2239 pub fn test_rem_euclid() {
2240 let p = Point3D::new(7.0, -7.0, 0.0);
2241 let s = Size3D::new(4.0, -4.0, 12.0);
2242
2243 assert_eq!(p.rem_euclid(&s), point3(3.0, 1.0, 0.0));
2244 assert_eq!((-p).rem_euclid(&s), point3(1.0, 3.0, 0.0));
2245 assert_eq!(p.rem_euclid(&-s), point3(3.0, 1.0, 0.0));
2246 }
2247
2248 #[test]
2249 pub fn test_div_euclid() {
2250 let p = Point3D::new(7.0, -7.0, 0.0);
2251 let s = Size3D::new(4.0, -4.0, 12.0);
2252
2253 assert_eq!(p.div_euclid(&s), point3(1.0, 2.0, 0.0));
2254 assert_eq!((-p).div_euclid(&s), point3(-2.0, -1.0, 0.0));
2255 assert_eq!(p.div_euclid(&-s), point3(-1.0, -2.0, 0.0));
2256 }
2257 }
2258}