1use super::UnknownUnit;
11use crate::approxord::{max, min};
12use crate::length::Length;
13use crate::num::*;
14use crate::scale::Scale;
15use crate::size::{Size2D, Size3D};
16use crate::vector::{vec2, vec3, Vector2D, Vector3D};
17use core::cmp::{Eq, PartialEq};
18use core::fmt;
19use core::hash::Hash;
20use core::marker::PhantomData;
21use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
22#[cfg(feature = "malloc_size_of")]
23use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
24#[cfg(feature = "mint")]
25use mint;
26use num_traits::{Euclid, NumCast};
27
28#[cfg(feature = "serde")]
29use serde;
30
31#[cfg(feature = "bytemuck")]
32use bytemuck::{Pod, Zeroable};
33
34#[repr(C)]
36pub struct Point2D<T, U> {
37 pub x: T,
38 pub y: T,
39 #[doc(hidden)]
40 pub _unit: PhantomData<U>,
41}
42
43impl<T: Copy, U> Copy for Point2D<T, U> {}
44
45impl<T: Clone, U> Clone for Point2D<T, U> {
46 fn clone(&self) -> Self {
47 Point2D {
48 x: self.x.clone(),
49 y: self.y.clone(),
50 _unit: PhantomData,
51 }
52 }
53}
54
55#[cfg(feature = "serde")]
56impl<'de, T, U> serde::Deserialize<'de> for Point2D<T, U>
57where
58 T: serde::Deserialize<'de>,
59{
60 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
61 where
62 D: serde::Deserializer<'de>,
63 {
64 let (x, y) = serde::Deserialize::deserialize(deserializer)?;
65 Ok(Point2D {
66 x,
67 y,
68 _unit: PhantomData,
69 })
70 }
71}
72
73#[cfg(feature = "serde")]
74impl<T, U> serde::Serialize for Point2D<T, U>
75where
76 T: serde::Serialize,
77{
78 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
79 where
80 S: serde::Serializer,
81 {
82 (&self.x, &self.y).serialize(serializer)
83 }
84}
85
86#[cfg(feature = "arbitrary")]
87impl<'a, T, U> arbitrary::Arbitrary<'a> for Point2D<T, U>
88where
89 T: arbitrary::Arbitrary<'a>,
90{
91 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
92 let (x, y) = arbitrary::Arbitrary::arbitrary(u)?;
93 Ok(Point2D {
94 x,
95 y,
96 _unit: PhantomData,
97 })
98 }
99}
100
101#[cfg(feature = "bytemuck")]
102unsafe impl<T: Zeroable, U> Zeroable for Point2D<T, U> {}
103
104#[cfg(feature = "bytemuck")]
105unsafe impl<T: Pod, U: 'static> Pod for Point2D<T, U> {}
106
107#[cfg(feature = "malloc_size_of")]
108impl<T: MallocSizeOf, U> MallocSizeOf for Point2D<T, U> {
109 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
110 self.x.size_of(ops) + self.y.size_of(ops)
111 }
112}
113
114impl<T, U> Eq for Point2D<T, U> where T: Eq {}
115
116impl<T, U> PartialEq for Point2D<T, U>
117where
118 T: PartialEq,
119{
120 fn eq(&self, other: &Self) -> bool {
121 self.x == other.x && self.y == other.y
122 }
123}
124
125impl<T, U> Hash for Point2D<T, U>
126where
127 T: Hash,
128{
129 fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
130 self.x.hash(h);
131 self.y.hash(h);
132 }
133}
134
135mint_vec!(Point2D[x, y] = Point2);
136
137impl<T: fmt::Debug, U> fmt::Debug for Point2D<T, U> {
138 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
139 f.debug_tuple("").field(&self.x).field(&self.y).finish()
140 }
141}
142
143impl<T: Default, U> Default for Point2D<T, U> {
144 fn default() -> Self {
145 Point2D::new(Default::default(), Default::default())
146 }
147}
148
149impl<T, U> Point2D<T, U> {
150 #[inline]
152 pub fn origin() -> Self
153 where
154 T: Zero,
155 {
156 point2(Zero::zero(), Zero::zero())
157 }
158
159 #[inline]
161 pub fn zero() -> Self
162 where
163 T: Zero,
164 {
165 Self::origin()
166 }
167
168 #[inline]
170 pub const fn new(x: T, y: T) -> Self {
171 Point2D {
172 x,
173 y,
174 _unit: PhantomData,
175 }
176 }
177
178 #[inline]
180 pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self {
181 point2(x.0, y.0)
182 }
183
184 #[inline]
186 pub fn splat(v: T) -> Self
187 where
188 T: Clone,
189 {
190 Point2D {
191 x: v.clone(),
192 y: v,
193 _unit: PhantomData,
194 }
195 }
196
197 #[inline]
199 pub fn from_untyped(p: Point2D<T, UnknownUnit>) -> Self {
200 point2(p.x, p.y)
201 }
202
203 #[inline]
216 pub fn map<V, F: FnMut(T) -> V>(self, mut f: F) -> Point2D<V, U> {
217 point2(f(self.x), f(self.y))
218 }
219
220 #[inline]
234 pub fn zip<V, F: FnMut(T, T) -> V>(self, rhs: Self, mut f: F) -> Vector2D<V, U> {
235 vec2(f(self.x, rhs.x), f(self.y, rhs.y))
236 }
237}
238
239impl<T: Copy, U> Point2D<T, U> {
240 #[inline]
242 pub fn extend(self, z: T) -> Point3D<T, U> {
243 point3(self.x, self.y, z)
244 }
245
246 #[inline]
250 pub fn to_vector(self) -> Vector2D<T, U> {
251 Vector2D {
252 x: self.x,
253 y: self.y,
254 _unit: PhantomData,
255 }
256 }
257
258 #[inline]
271 pub fn yx(self) -> Self {
272 point2(self.y, self.x)
273 }
274
275 #[inline]
289 pub fn to_untyped(self) -> Point2D<T, UnknownUnit> {
290 point2(self.x, self.y)
291 }
292
293 #[inline]
308 pub fn cast_unit<V>(self) -> Point2D<T, V> {
309 point2(self.x, self.y)
310 }
311
312 #[inline]
325 pub fn to_array(self) -> [T; 2] {
326 [self.x, self.y]
327 }
328
329 #[inline]
342 pub fn to_tuple(self) -> (T, T) {
343 (self.x, self.y)
344 }
345
346 #[inline]
348 pub fn to_3d(self) -> Point3D<T, U>
349 where
350 T: Zero,
351 {
352 point3(self.x, self.y, Zero::zero())
353 }
354
355 #[inline]
366 #[must_use]
367 pub fn round(self) -> Self
368 where
369 T: Round,
370 {
371 point2(self.x.round(), self.y.round())
372 }
373
374 #[inline]
385 #[must_use]
386 pub fn ceil(self) -> Self
387 where
388 T: Ceil,
389 {
390 point2(self.x.ceil(), self.y.ceil())
391 }
392
393 #[inline]
404 #[must_use]
405 pub fn floor(self) -> Self
406 where
407 T: Floor,
408 {
409 point2(self.x.floor(), self.y.floor())
410 }
411
412 #[inline]
430 pub fn lerp(self, other: Self, t: T) -> Self
431 where
432 T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
433 {
434 let one_t = T::one() - t;
435 point2(one_t * self.x + t * other.x, one_t * self.y + t * other.y)
436 }
437}
438
439impl<T: PartialOrd, U> Point2D<T, U> {
440 #[inline]
441 pub fn min(self, other: Self) -> Self {
442 point2(min(self.x, other.x), min(self.y, other.y))
443 }
444
445 #[inline]
446 pub fn max(self, other: Self) -> Self {
447 point2(max(self.x, other.x), max(self.y, other.y))
448 }
449
450 #[inline]
455 pub fn clamp(self, start: Self, end: Self) -> Self
456 where
457 T: Copy,
458 {
459 self.max(start).min(end)
460 }
461}
462
463impl<T: NumCast + Copy, U> Point2D<T, U> {
464 #[inline]
470 pub fn cast<NewT: NumCast>(self) -> Point2D<NewT, U> {
471 self.try_cast().unwrap()
472 }
473
474 pub fn try_cast<NewT: NumCast>(self) -> Option<Point2D<NewT, U>> {
480 match (NumCast::from(self.x), NumCast::from(self.y)) {
481 (Some(x), Some(y)) => Some(point2(x, y)),
482 _ => None,
483 }
484 }
485
486 #[inline]
490 pub fn to_f32(self) -> Point2D<f32, U> {
491 self.cast()
492 }
493
494 #[inline]
496 pub fn to_f64(self) -> Point2D<f64, U> {
497 self.cast()
498 }
499
500 #[inline]
506 pub fn to_usize(self) -> Point2D<usize, U> {
507 self.cast()
508 }
509
510 #[inline]
516 pub fn to_u32(self) -> Point2D<u32, U> {
517 self.cast()
518 }
519
520 #[inline]
526 pub fn to_i32(self) -> Point2D<i32, U> {
527 self.cast()
528 }
529
530 #[inline]
536 pub fn to_i64(self) -> Point2D<i64, U> {
537 self.cast()
538 }
539}
540
541#[cfg(any(feature = "std", feature = "libm"))]
542mod point2d_float {
543 use super::Point2D;
544 use crate::{approxeq::ApproxEq, point2};
545 use core::ops::Sub;
546 use num_traits::{real::Real, Float};
547
548 impl<T: Float, U> Point2D<T, U> {
549 #[inline]
551 pub fn is_finite(self) -> bool {
552 self.x.is_finite() && self.y.is_finite()
553 }
554 }
555
556 impl<T: Real + Sub<T, Output = T>, U> Point2D<T, U> {
557 #[inline]
558 pub fn distance_to(self, other: Self) -> T {
559 (self - other).length()
560 }
561 }
562
563 impl<T: ApproxEq<T>, U> ApproxEq<Point2D<T, U>> for Point2D<T, U> {
564 #[inline]
565 fn approx_epsilon() -> Self {
566 point2(T::approx_epsilon(), T::approx_epsilon())
567 }
568
569 #[inline]
570 fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
571 self.x.approx_eq_eps(&other.x, &eps.x) && self.y.approx_eq_eps(&other.y, &eps.y)
572 }
573 }
574}
575
576impl<T: Copy + Add<T, Output = T>, U> Point2D<T, U> {
577 #[inline]
578 pub fn add_size(self, other: &Size2D<T, U>) -> Self {
579 point2(self.x + other.width, self.y + other.height)
580 }
581}
582
583impl<T: Neg, U> Neg for Point2D<T, U> {
584 type Output = Point2D<T::Output, U>;
585
586 #[inline]
587 fn neg(self) -> Self::Output {
588 point2(-self.x, -self.y)
589 }
590}
591
592impl<T: Add, U> Add<Size2D<T, U>> for Point2D<T, U> {
593 type Output = Point2D<T::Output, U>;
594
595 #[inline]
596 fn add(self, other: Size2D<T, U>) -> Self::Output {
597 point2(self.x + other.width, self.y + other.height)
598 }
599}
600
601impl<T: AddAssign, U> AddAssign<Size2D<T, U>> for Point2D<T, U> {
602 #[inline]
603 fn add_assign(&mut self, other: Size2D<T, U>) {
604 self.x += other.width;
605 self.y += other.height;
606 }
607}
608
609impl<T: Add, U> Add<Vector2D<T, U>> for Point2D<T, U> {
610 type Output = Point2D<T::Output, U>;
611
612 #[inline]
613 fn add(self, other: Vector2D<T, U>) -> Self::Output {
614 point2(self.x + other.x, self.y + other.y)
615 }
616}
617
618impl<T: Copy + Add<T, Output = T>, U> AddAssign<Vector2D<T, U>> for Point2D<T, U> {
619 #[inline]
620 fn add_assign(&mut self, other: Vector2D<T, U>) {
621 *self = *self + other;
622 }
623}
624
625impl<T: Sub, U> Sub for Point2D<T, U> {
626 type Output = Vector2D<T::Output, U>;
627
628 #[inline]
629 fn sub(self, other: Self) -> Self::Output {
630 vec2(self.x - other.x, self.y - other.y)
631 }
632}
633
634impl<T: Sub, U> Sub<Size2D<T, U>> for Point2D<T, U> {
635 type Output = Point2D<T::Output, U>;
636
637 #[inline]
638 fn sub(self, other: Size2D<T, U>) -> Self::Output {
639 point2(self.x - other.width, self.y - other.height)
640 }
641}
642
643impl<T: SubAssign, U> SubAssign<Size2D<T, U>> for Point2D<T, U> {
644 #[inline]
645 fn sub_assign(&mut self, other: Size2D<T, U>) {
646 self.x -= other.width;
647 self.y -= other.height;
648 }
649}
650
651impl<T: Sub, U> Sub<Vector2D<T, U>> for Point2D<T, U> {
652 type Output = Point2D<T::Output, U>;
653
654 #[inline]
655 fn sub(self, other: Vector2D<T, U>) -> Self::Output {
656 point2(self.x - other.x, self.y - other.y)
657 }
658}
659
660impl<T: Copy + Sub<T, Output = T>, U> SubAssign<Vector2D<T, U>> for Point2D<T, U> {
661 #[inline]
662 fn sub_assign(&mut self, other: Vector2D<T, U>) {
663 *self = *self - other;
664 }
665}
666
667impl<T: Copy + Mul, U> Mul<T> for Point2D<T, U> {
668 type Output = Point2D<T::Output, U>;
669
670 #[inline]
671 fn mul(self, scale: T) -> Self::Output {
672 point2(self.x * scale, self.y * scale)
673 }
674}
675
676impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Point2D<T, U> {
677 #[inline]
678 fn mul_assign(&mut self, scale: T) {
679 *self = *self * scale;
680 }
681}
682
683impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Point2D<T, U1> {
684 type Output = Point2D<T::Output, U2>;
685
686 #[inline]
687 fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
688 point2(self.x * scale.0, self.y * scale.0)
689 }
690}
691
692impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Point2D<T, U> {
693 #[inline]
694 fn mul_assign(&mut self, scale: Scale<T, U, U>) {
695 self.x *= scale.0;
696 self.y *= scale.0;
697 }
698}
699
700impl<T: Copy + Div, U> Div<T> for Point2D<T, U> {
701 type Output = Point2D<T::Output, U>;
702
703 #[inline]
704 fn div(self, scale: T) -> Self::Output {
705 point2(self.x / scale, self.y / scale)
706 }
707}
708
709impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Point2D<T, U> {
710 #[inline]
711 fn div_assign(&mut self, scale: T) {
712 *self = *self / scale;
713 }
714}
715
716impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Point2D<T, U2> {
717 type Output = Point2D<T::Output, U1>;
718
719 #[inline]
720 fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
721 point2(self.x / scale.0, self.y / scale.0)
722 }
723}
724
725impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Point2D<T, U> {
726 #[inline]
727 fn div_assign(&mut self, scale: Scale<T, U, U>) {
728 self.x /= scale.0;
729 self.y /= scale.0;
730 }
731}
732
733impl<T: Zero, U> Zero for Point2D<T, U> {
734 #[inline]
735 fn zero() -> Self {
736 Self::origin()
737 }
738}
739
740impl<T: Round, U> Round for Point2D<T, U> {
741 #[inline]
743 fn round(self) -> Self {
744 self.round()
745 }
746}
747
748impl<T: Ceil, U> Ceil for Point2D<T, U> {
749 #[inline]
751 fn ceil(self) -> Self {
752 self.ceil()
753 }
754}
755
756impl<T: Floor, U> Floor for Point2D<T, U> {
757 #[inline]
759 fn floor(self) -> Self {
760 self.floor()
761 }
762}
763
764impl<T: Euclid, U> Point2D<T, U> {
765 #[inline]
781 pub fn rem_euclid(&self, other: &Size2D<T, U>) -> Self {
782 point2(
783 self.x.rem_euclid(&other.width),
784 self.y.rem_euclid(&other.height),
785 )
786 }
787
788 #[inline]
804 pub fn div_euclid(&self, other: &Size2D<T, U>) -> Self {
805 point2(
806 self.x.div_euclid(&other.width),
807 self.y.div_euclid(&other.height),
808 )
809 }
810}
811
812impl<T, U> From<Point2D<T, U>> for [T; 2] {
813 fn from(p: Point2D<T, U>) -> Self {
814 [p.x, p.y]
815 }
816}
817
818impl<T, U> From<[T; 2]> for Point2D<T, U> {
819 fn from([x, y]: [T; 2]) -> Self {
820 point2(x, y)
821 }
822}
823
824impl<T, U> From<Point2D<T, U>> for (T, T) {
825 fn from(p: Point2D<T, U>) -> Self {
826 (p.x, p.y)
827 }
828}
829
830impl<T, U> From<(T, T)> for Point2D<T, U> {
831 fn from(tuple: (T, T)) -> Self {
832 point2(tuple.0, tuple.1)
833 }
834}
835
836#[repr(C)]
838pub struct Point3D<T, U> {
839 pub x: T,
840 pub y: T,
841 pub z: T,
842 #[doc(hidden)]
843 pub _unit: PhantomData<U>,
844}
845
846mint_vec!(Point3D[x, y, z] = Point3);
847
848impl<T: Copy, U> Copy for Point3D<T, U> {}
849
850impl<T: Clone, U> Clone for Point3D<T, U> {
851 fn clone(&self) -> Self {
852 Point3D {
853 x: self.x.clone(),
854 y: self.y.clone(),
855 z: self.z.clone(),
856 _unit: PhantomData,
857 }
858 }
859}
860
861#[cfg(feature = "serde")]
862impl<'de, T, U> serde::Deserialize<'de> for Point3D<T, U>
863where
864 T: serde::Deserialize<'de>,
865{
866 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
867 where
868 D: serde::Deserializer<'de>,
869 {
870 let (x, y, z) = serde::Deserialize::deserialize(deserializer)?;
871 Ok(Point3D {
872 x,
873 y,
874 z,
875 _unit: PhantomData,
876 })
877 }
878}
879
880#[cfg(feature = "serde")]
881impl<T, U> serde::Serialize for Point3D<T, U>
882where
883 T: serde::Serialize,
884{
885 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
886 where
887 S: serde::Serializer,
888 {
889 (&self.x, &self.y, &self.z).serialize(serializer)
890 }
891}
892
893#[cfg(feature = "arbitrary")]
894impl<'a, T, U> arbitrary::Arbitrary<'a> for Point3D<T, U>
895where
896 T: arbitrary::Arbitrary<'a>,
897{
898 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
899 let (x, y, z) = arbitrary::Arbitrary::arbitrary(u)?;
900 Ok(Point3D {
901 x,
902 y,
903 z,
904 _unit: PhantomData,
905 })
906 }
907}
908
909#[cfg(feature = "bytemuck")]
910unsafe impl<T: Zeroable, U> Zeroable for Point3D<T, U> {}
911
912#[cfg(feature = "bytemuck")]
913unsafe impl<T: Pod, U: 'static> Pod for Point3D<T, U> {}
914
915#[cfg(feature = "malloc_size_of")]
916impl<T: MallocSizeOf, U> MallocSizeOf for Point3D<T, U> {
917 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
918 self.x.size_of(ops) + self.y.size_of(ops) + self.z.size_of(ops)
919 }
920}
921
922impl<T, U> Eq for Point3D<T, U> where T: Eq {}
923
924impl<T, U> PartialEq for Point3D<T, U>
925where
926 T: PartialEq,
927{
928 fn eq(&self, other: &Self) -> bool {
929 self.x == other.x && self.y == other.y && self.z == other.z
930 }
931}
932
933impl<T, U> Hash for Point3D<T, U>
934where
935 T: Hash,
936{
937 fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
938 self.x.hash(h);
939 self.y.hash(h);
940 self.z.hash(h);
941 }
942}
943
944impl<T: fmt::Debug, U> fmt::Debug for Point3D<T, U> {
945 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
946 f.debug_tuple("")
947 .field(&self.x)
948 .field(&self.y)
949 .field(&self.z)
950 .finish()
951 }
952}
953
954impl<T: Default, U> Default for Point3D<T, U> {
955 fn default() -> Self {
956 Point3D::new(Default::default(), Default::default(), Default::default())
957 }
958}
959
960impl<T, U> Point3D<T, U> {
961 #[inline]
963 pub fn origin() -> Self
964 where
965 T: Zero,
966 {
967 point3(Zero::zero(), Zero::zero(), Zero::zero())
968 }
969
970 #[inline]
972 pub fn zero() -> Self
973 where
974 T: Zero,
975 {
976 Self::origin()
977 }
978
979 #[inline]
981 pub const fn new(x: T, y: T, z: T) -> Self {
982 Point3D {
983 x,
984 y,
985 z,
986 _unit: PhantomData,
987 }
988 }
989
990 #[inline]
992 pub fn from_lengths(x: Length<T, U>, y: Length<T, U>, z: Length<T, U>) -> Self {
993 point3(x.0, y.0, z.0)
994 }
995
996 #[inline]
998 pub fn splat(v: T) -> Self
999 where
1000 T: Clone,
1001 {
1002 Point3D {
1003 x: v.clone(),
1004 y: v.clone(),
1005 z: v,
1006 _unit: PhantomData,
1007 }
1008 }
1009
1010 #[inline]
1012 pub fn from_untyped(p: Point3D<T, UnknownUnit>) -> Self {
1013 point3(p.x, p.y, p.z)
1014 }
1015
1016 #[inline]
1029 pub fn map<V, F: FnMut(T) -> V>(self, mut f: F) -> Point3D<V, U> {
1030 point3(f(self.x), f(self.y), f(self.z))
1031 }
1032
1033 #[inline]
1047 pub fn zip<V, F: FnMut(T, T) -> V>(self, rhs: Self, mut f: F) -> Vector3D<V, U> {
1048 vec3(f(self.x, rhs.x), f(self.y, rhs.y), f(self.z, rhs.z))
1049 }
1050}
1051
1052impl<T: Copy, U> Point3D<T, U> {
1053 #[inline]
1057 pub fn to_vector(self) -> Vector3D<T, U> {
1058 Vector3D {
1059 x: self.x,
1060 y: self.y,
1061 z: self.z,
1062 _unit: PhantomData,
1063 }
1064 }
1065
1066 #[inline]
1068 pub fn xy(self) -> Point2D<T, U> {
1069 point2(self.x, self.y)
1070 }
1071
1072 #[inline]
1074 pub fn xz(self) -> Point2D<T, U> {
1075 point2(self.x, self.z)
1076 }
1077
1078 #[inline]
1080 pub fn yz(self) -> Point2D<T, U> {
1081 point2(self.y, self.z)
1082 }
1083
1084 #[inline]
1097 pub fn to_array(self) -> [T; 3] {
1098 [self.x, self.y, self.z]
1099 }
1100
1101 #[inline]
1102 pub fn to_array_4d(self) -> [T; 4]
1103 where
1104 T: One,
1105 {
1106 [self.x, self.y, self.z, One::one()]
1107 }
1108
1109 #[inline]
1122 pub fn to_tuple(self) -> (T, T, T) {
1123 (self.x, self.y, self.z)
1124 }
1125
1126 #[inline]
1127 pub fn to_tuple_4d(self) -> (T, T, T, T)
1128 where
1129 T: One,
1130 {
1131 (self.x, self.y, self.z, One::one())
1132 }
1133
1134 #[inline]
1149 pub fn to_untyped(self) -> Point3D<T, UnknownUnit> {
1150 point3(self.x, self.y, self.z)
1151 }
1152
1153 #[inline]
1169 pub fn cast_unit<V>(self) -> Point3D<T, V> {
1170 point3(self.x, self.y, self.z)
1171 }
1172
1173 #[inline]
1175 pub fn to_2d(self) -> Point2D<T, U> {
1176 self.xy()
1177 }
1178
1179 #[inline]
1190 #[must_use]
1191 pub fn round(self) -> Self
1192 where
1193 T: Round,
1194 {
1195 point3(self.x.round(), self.y.round(), self.z.round())
1196 }
1197
1198 #[inline]
1209 #[must_use]
1210 pub fn ceil(self) -> Self
1211 where
1212 T: Ceil,
1213 {
1214 point3(self.x.ceil(), self.y.ceil(), self.z.ceil())
1215 }
1216
1217 #[inline]
1228 #[must_use]
1229 pub fn floor(self) -> Self
1230 where
1231 T: Floor,
1232 {
1233 point3(self.x.floor(), self.y.floor(), self.z.floor())
1234 }
1235
1236 #[inline]
1254 pub fn lerp(self, other: Self, t: T) -> Self
1255 where
1256 T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
1257 {
1258 let one_t = T::one() - t;
1259 point3(
1260 one_t * self.x + t * other.x,
1261 one_t * self.y + t * other.y,
1262 one_t * self.z + t * other.z,
1263 )
1264 }
1265}
1266
1267impl<T: PartialOrd, U> Point3D<T, U> {
1268 #[inline]
1269 pub fn min(self, other: Self) -> Self {
1270 point3(
1271 min(self.x, other.x),
1272 min(self.y, other.y),
1273 min(self.z, other.z),
1274 )
1275 }
1276
1277 #[inline]
1278 pub fn max(self, other: Self) -> Self {
1279 point3(
1280 max(self.x, other.x),
1281 max(self.y, other.y),
1282 max(self.z, other.z),
1283 )
1284 }
1285
1286 #[inline]
1291 pub fn clamp(self, start: Self, end: Self) -> Self
1292 where
1293 T: Copy,
1294 {
1295 self.max(start).min(end)
1296 }
1297}
1298
1299impl<T: NumCast + Copy, U> Point3D<T, U> {
1300 #[inline]
1306 pub fn cast<NewT: NumCast>(self) -> Point3D<NewT, U> {
1307 self.try_cast().unwrap()
1308 }
1309
1310 pub fn try_cast<NewT: NumCast>(self) -> Option<Point3D<NewT, U>> {
1316 match (
1317 NumCast::from(self.x),
1318 NumCast::from(self.y),
1319 NumCast::from(self.z),
1320 ) {
1321 (Some(x), Some(y), Some(z)) => Some(point3(x, y, z)),
1322 _ => None,
1323 }
1324 }
1325
1326 #[inline]
1330 pub fn to_f32(self) -> Point3D<f32, U> {
1331 self.cast()
1332 }
1333
1334 #[inline]
1336 pub fn to_f64(self) -> Point3D<f64, U> {
1337 self.cast()
1338 }
1339
1340 #[inline]
1346 pub fn to_usize(self) -> Point3D<usize, U> {
1347 self.cast()
1348 }
1349
1350 #[inline]
1356 pub fn to_u32(self) -> Point3D<u32, U> {
1357 self.cast()
1358 }
1359
1360 #[inline]
1366 pub fn to_i32(self) -> Point3D<i32, U> {
1367 self.cast()
1368 }
1369
1370 #[inline]
1376 pub fn to_i64(self) -> Point3D<i64, U> {
1377 self.cast()
1378 }
1379}
1380
1381impl<T: Copy + Add<T, Output = T>, U> Point3D<T, U> {
1382 #[inline]
1383 pub fn add_size(self, other: Size3D<T, U>) -> Self {
1384 point3(
1385 self.x + other.width,
1386 self.y + other.height,
1387 self.z + other.depth,
1388 )
1389 }
1390}
1391
1392impl<T: Neg, U> Neg for Point3D<T, U> {
1393 type Output = Point3D<T::Output, U>;
1394
1395 #[inline]
1396 fn neg(self) -> Self::Output {
1397 point3(-self.x, -self.y, -self.z)
1398 }
1399}
1400
1401impl<T: Add, U> Add<Size3D<T, U>> for Point3D<T, U> {
1402 type Output = Point3D<T::Output, U>;
1403
1404 #[inline]
1405 fn add(self, other: Size3D<T, U>) -> Self::Output {
1406 point3(
1407 self.x + other.width,
1408 self.y + other.height,
1409 self.z + other.depth,
1410 )
1411 }
1412}
1413
1414impl<T: AddAssign, U> AddAssign<Size3D<T, U>> for Point3D<T, U> {
1415 #[inline]
1416 fn add_assign(&mut self, other: Size3D<T, U>) {
1417 self.x += other.width;
1418 self.y += other.height;
1419 self.z += other.depth;
1420 }
1421}
1422
1423impl<T: Add, U> Add<Vector3D<T, U>> for Point3D<T, U> {
1424 type Output = Point3D<T::Output, U>;
1425
1426 #[inline]
1427 fn add(self, other: Vector3D<T, U>) -> Self::Output {
1428 point3(self.x + other.x, self.y + other.y, self.z + other.z)
1429 }
1430}
1431
1432impl<T: Copy + Add<T, Output = T>, U> AddAssign<Vector3D<T, U>> for Point3D<T, U> {
1433 #[inline]
1434 fn add_assign(&mut self, other: Vector3D<T, U>) {
1435 *self = *self + other;
1436 }
1437}
1438
1439impl<T: Sub, U> Sub for Point3D<T, U> {
1440 type Output = Vector3D<T::Output, U>;
1441
1442 #[inline]
1443 fn sub(self, other: Self) -> Self::Output {
1444 vec3(self.x - other.x, self.y - other.y, self.z - other.z)
1445 }
1446}
1447
1448impl<T: Sub, U> Sub<Size3D<T, U>> for Point3D<T, U> {
1449 type Output = Point3D<T::Output, U>;
1450
1451 #[inline]
1452 fn sub(self, other: Size3D<T, U>) -> Self::Output {
1453 point3(
1454 self.x - other.width,
1455 self.y - other.height,
1456 self.z - other.depth,
1457 )
1458 }
1459}
1460
1461impl<T: SubAssign, U> SubAssign<Size3D<T, U>> for Point3D<T, U> {
1462 #[inline]
1463 fn sub_assign(&mut self, other: Size3D<T, U>) {
1464 self.x -= other.width;
1465 self.y -= other.height;
1466 self.z -= other.depth;
1467 }
1468}
1469
1470impl<T: Sub, U> Sub<Vector3D<T, U>> for Point3D<T, U> {
1471 type Output = Point3D<T::Output, U>;
1472
1473 #[inline]
1474 fn sub(self, other: Vector3D<T, U>) -> Self::Output {
1475 point3(self.x - other.x, self.y - other.y, self.z - other.z)
1476 }
1477}
1478
1479impl<T: Copy + Sub<T, Output = T>, U> SubAssign<Vector3D<T, U>> for Point3D<T, U> {
1480 #[inline]
1481 fn sub_assign(&mut self, other: Vector3D<T, U>) {
1482 *self = *self - other;
1483 }
1484}
1485
1486impl<T: Copy + Mul, U> Mul<T> for Point3D<T, U> {
1487 type Output = Point3D<T::Output, U>;
1488
1489 #[inline]
1490 fn mul(self, scale: T) -> Self::Output {
1491 point3(self.x * scale, self.y * scale, self.z * scale)
1492 }
1493}
1494
1495impl<T: Copy + MulAssign, U> MulAssign<T> for Point3D<T, U> {
1496 #[inline]
1497 fn mul_assign(&mut self, scale: T) {
1498 self.x *= scale;
1499 self.y *= scale;
1500 self.z *= scale;
1501 }
1502}
1503
1504impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Point3D<T, U1> {
1505 type Output = Point3D<T::Output, U2>;
1506
1507 #[inline]
1508 fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
1509 point3(self.x * scale.0, self.y * scale.0, self.z * scale.0)
1510 }
1511}
1512
1513impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Point3D<T, U> {
1514 #[inline]
1515 fn mul_assign(&mut self, scale: Scale<T, U, U>) {
1516 *self *= scale.0;
1517 }
1518}
1519
1520impl<T: Copy + Div, U> Div<T> for Point3D<T, U> {
1521 type Output = Point3D<T::Output, U>;
1522
1523 #[inline]
1524 fn div(self, scale: T) -> Self::Output {
1525 point3(self.x / scale, self.y / scale, self.z / scale)
1526 }
1527}
1528
1529impl<T: Copy + DivAssign, U> DivAssign<T> for Point3D<T, U> {
1530 #[inline]
1531 fn div_assign(&mut self, scale: T) {
1532 self.x /= scale;
1533 self.y /= scale;
1534 self.z /= scale;
1535 }
1536}
1537
1538impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Point3D<T, U2> {
1539 type Output = Point3D<T::Output, U1>;
1540
1541 #[inline]
1542 fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
1543 point3(self.x / scale.0, self.y / scale.0, self.z / scale.0)
1544 }
1545}
1546
1547impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Point3D<T, U> {
1548 #[inline]
1549 fn div_assign(&mut self, scale: Scale<T, U, U>) {
1550 *self /= scale.0;
1551 }
1552}
1553
1554impl<T: Zero, U> Zero for Point3D<T, U> {
1555 #[inline]
1556 fn zero() -> Self {
1557 Self::origin()
1558 }
1559}
1560
1561impl<T: Round, U> Round for Point3D<T, U> {
1562 #[inline]
1564 fn round(self) -> Self {
1565 self.round()
1566 }
1567}
1568
1569impl<T: Ceil, U> Ceil for Point3D<T, U> {
1570 #[inline]
1572 fn ceil(self) -> Self {
1573 self.ceil()
1574 }
1575}
1576
1577impl<T: Floor, U> Floor for Point3D<T, U> {
1578 #[inline]
1580 fn floor(self) -> Self {
1581 self.floor()
1582 }
1583}
1584
1585impl<T: Euclid, U> Point3D<T, U> {
1586 #[inline]
1602 pub fn rem_euclid(&self, other: &Size3D<T, U>) -> Self {
1603 point3(
1604 self.x.rem_euclid(&other.width),
1605 self.y.rem_euclid(&other.height),
1606 self.z.rem_euclid(&other.depth),
1607 )
1608 }
1609
1610 #[inline]
1626 pub fn div_euclid(&self, other: &Size3D<T, U>) -> Self {
1627 point3(
1628 self.x.div_euclid(&other.width),
1629 self.y.div_euclid(&other.height),
1630 self.z.div_euclid(&other.depth),
1631 )
1632 }
1633}
1634
1635impl<T, U> From<Point3D<T, U>> for [T; 3] {
1636 fn from(p: Point3D<T, U>) -> Self {
1637 [p.x, p.y, p.z]
1638 }
1639}
1640
1641impl<T, U> From<[T; 3]> for Point3D<T, U> {
1642 fn from([x, y, z]: [T; 3]) -> Self {
1643 point3(x, y, z)
1644 }
1645}
1646
1647impl<T, U> From<Point3D<T, U>> for (T, T, T) {
1648 fn from(p: Point3D<T, U>) -> Self {
1649 (p.x, p.y, p.z)
1650 }
1651}
1652
1653impl<T, U> From<(T, T, T)> for Point3D<T, U> {
1654 fn from(tuple: (T, T, T)) -> Self {
1655 point3(tuple.0, tuple.1, tuple.2)
1656 }
1657}
1658
1659#[inline]
1661pub const fn point2<T, U>(x: T, y: T) -> Point2D<T, U> {
1662 Point2D {
1663 x,
1664 y,
1665 _unit: PhantomData,
1666 }
1667}
1668
1669#[inline]
1671pub const fn point3<T, U>(x: T, y: T, z: T) -> Point3D<T, U> {
1672 Point3D {
1673 x,
1674 y,
1675 z,
1676 _unit: PhantomData,
1677 }
1678}
1679
1680#[cfg(any(feature = "std", feature = "libm"))]
1681mod point3d_float {
1682 use super::{point3, Point3D};
1683 use crate::approxeq::ApproxEq;
1684 use core::ops::Sub;
1685 use num_traits::{real::Real, Float};
1686
1687 impl<T: Float, U> Point3D<T, U> {
1688 #[inline]
1690 pub fn is_finite(self) -> bool {
1691 self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
1692 }
1693 }
1694
1695 impl<T: Real + Sub<T, Output = T>, U> Point3D<T, U> {
1696 #[inline]
1697 pub fn distance_to(self, other: Self) -> T {
1698 (self - other).length()
1699 }
1700 }
1701
1702 impl<T: ApproxEq<T>, U> ApproxEq<Point3D<T, U>> for Point3D<T, U> {
1703 #[inline]
1704 fn approx_epsilon() -> Self {
1705 point3(
1706 T::approx_epsilon(),
1707 T::approx_epsilon(),
1708 T::approx_epsilon(),
1709 )
1710 }
1711
1712 #[inline]
1713 fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
1714 self.x.approx_eq_eps(&other.x, &eps.x)
1715 && self.y.approx_eq_eps(&other.y, &eps.y)
1716 && self.z.approx_eq_eps(&other.z, &eps.z)
1717 }
1718 }
1719}
1720
1721#[cfg(test)]
1722#[cfg(any(feature = "std", feature = "libm"))]
1723mod point2d {
1724 use crate::default::Point2D;
1725 use crate::point2;
1726
1727 #[cfg(feature = "mint")]
1728 use mint;
1729
1730 #[test]
1731 pub fn test_min() {
1732 let p1 = Point2D::new(1.0, 3.0);
1733 let p2 = Point2D::new(2.0, 2.0);
1734
1735 let result = p1.min(p2);
1736
1737 assert_eq!(result, Point2D::new(1.0, 2.0));
1738 }
1739
1740 #[test]
1741 pub fn test_max() {
1742 let p1 = Point2D::new(1.0, 3.0);
1743 let p2 = Point2D::new(2.0, 2.0);
1744
1745 let result = p1.max(p2);
1746
1747 assert_eq!(result, Point2D::new(2.0, 3.0));
1748 }
1749
1750 #[cfg(feature = "mint")]
1751 #[test]
1752 pub fn test_mint() {
1753 let p1 = Point2D::new(1.0, 3.0);
1754 let pm: mint::Point2<_> = p1.into();
1755 let p2 = Point2D::from(pm);
1756
1757 assert_eq!(p1, p2);
1758 }
1759
1760 #[test]
1761 pub fn test_conv_vector() {
1762 for i in 0..100 {
1763 let x = i as f32 * 0.012345;
1765 let y = i as f32 * 0.987654;
1766 let p: Point2D<f32> = point2(x, y);
1767 assert_eq!(p.to_vector().to_point(), p);
1768 }
1769 }
1770
1771 #[test]
1772 pub fn test_swizzling() {
1773 let p: Point2D<i32> = point2(1, 2);
1774 assert_eq!(p.yx(), point2(2, 1));
1775 }
1776
1777 #[test]
1778 pub fn test_distance_to() {
1779 let p1 = Point2D::new(1.0, 2.0);
1780 let p2 = Point2D::new(2.0, 2.0);
1781
1782 assert_eq!(p1.distance_to(p2), 1.0);
1783
1784 let p1 = Point2D::new(1.0, 2.0);
1785 let p2 = Point2D::new(1.0, 4.0);
1786
1787 assert_eq!(p1.distance_to(p2), 2.0);
1788 }
1789
1790 mod ops {
1791 use crate::default::Point2D;
1792 use crate::scale::Scale;
1793 use crate::{size2, vec2, Vector2D};
1794
1795 pub enum Mm {}
1796 pub enum Cm {}
1797
1798 pub type Point2DMm<T> = crate::Point2D<T, Mm>;
1799 pub type Point2DCm<T> = crate::Point2D<T, Cm>;
1800
1801 #[test]
1802 pub fn test_neg() {
1803 assert_eq!(-Point2D::new(1.0, 2.0), Point2D::new(-1.0, -2.0));
1804 assert_eq!(-Point2D::new(0.0, 0.0), Point2D::new(-0.0, -0.0));
1805 assert_eq!(-Point2D::new(-1.0, -2.0), Point2D::new(1.0, 2.0));
1806 }
1807
1808 #[test]
1809 pub fn test_add_size() {
1810 let p1 = Point2DMm::new(1.0, 2.0);
1811 let p2 = size2(3.0, 4.0);
1812
1813 let result = p1 + p2;
1814
1815 assert_eq!(result, Point2DMm::new(4.0, 6.0));
1816 }
1817
1818 #[test]
1819 pub fn test_add_assign_size() {
1820 let mut p1 = Point2DMm::new(1.0, 2.0);
1821
1822 p1 += size2(3.0, 4.0);
1823
1824 assert_eq!(p1, Point2DMm::new(4.0, 6.0));
1825 }
1826
1827 #[test]
1828 pub fn test_add_vec() {
1829 let p1 = Point2DMm::new(1.0, 2.0);
1830 let p2 = vec2(3.0, 4.0);
1831
1832 let result = p1 + p2;
1833
1834 assert_eq!(result, Point2DMm::new(4.0, 6.0));
1835 }
1836
1837 #[test]
1838 pub fn test_add_assign_vec() {
1839 let mut p1 = Point2DMm::new(1.0, 2.0);
1840
1841 p1 += vec2(3.0, 4.0);
1842
1843 assert_eq!(p1, Point2DMm::new(4.0, 6.0));
1844 }
1845
1846 #[test]
1847 pub fn test_sub() {
1848 let p1 = Point2DMm::new(1.0, 2.0);
1849 let p2 = Point2DMm::new(3.0, 4.0);
1850
1851 let result = p1 - p2;
1852
1853 assert_eq!(result, Vector2D::<_, Mm>::new(-2.0, -2.0));
1854 }
1855
1856 #[test]
1857 pub fn test_sub_size() {
1858 let p1 = Point2DMm::new(1.0, 2.0);
1859 let p2 = size2(3.0, 4.0);
1860
1861 let result = p1 - p2;
1862
1863 assert_eq!(result, Point2DMm::new(-2.0, -2.0));
1864 }
1865
1866 #[test]
1867 pub fn test_sub_assign_size() {
1868 let mut p1 = Point2DMm::new(1.0, 2.0);
1869
1870 p1 -= size2(3.0, 4.0);
1871
1872 assert_eq!(p1, Point2DMm::new(-2.0, -2.0));
1873 }
1874
1875 #[test]
1876 pub fn test_sub_vec() {
1877 let p1 = Point2DMm::new(1.0, 2.0);
1878 let p2 = vec2(3.0, 4.0);
1879
1880 let result = p1 - p2;
1881
1882 assert_eq!(result, Point2DMm::new(-2.0, -2.0));
1883 }
1884
1885 #[test]
1886 pub fn test_sub_assign_vec() {
1887 let mut p1 = Point2DMm::new(1.0, 2.0);
1888
1889 p1 -= vec2(3.0, 4.0);
1890
1891 assert_eq!(p1, Point2DMm::new(-2.0, -2.0));
1892 }
1893
1894 #[test]
1895 pub fn test_mul_scalar() {
1896 let p1: Point2D<f32> = Point2D::new(3.0, 5.0);
1897
1898 let result = p1 * 5.0;
1899
1900 assert_eq!(result, Point2D::new(15.0, 25.0));
1901 }
1902
1903 #[test]
1904 pub fn test_mul_assign_scalar() {
1905 let mut p1 = Point2D::new(3.0, 5.0);
1906
1907 p1 *= 5.0;
1908
1909 assert_eq!(p1, Point2D::new(15.0, 25.0));
1910 }
1911
1912 #[test]
1913 pub fn test_mul_scale() {
1914 let p1 = Point2DMm::new(1.0, 2.0);
1915 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
1916
1917 let result = p1 * cm_per_mm;
1918
1919 assert_eq!(result, Point2DCm::new(0.1, 0.2));
1920 }
1921
1922 #[test]
1923 pub fn test_mul_assign_scale() {
1924 let mut p1 = Point2DMm::new(1.0, 2.0);
1925 let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
1926
1927 p1 *= scale;
1928
1929 assert_eq!(p1, Point2DMm::new(0.1, 0.2));
1930 }
1931
1932 #[test]
1933 pub fn test_div_scalar() {
1934 let p1: Point2D<f32> = Point2D::new(15.0, 25.0);
1935
1936 let result = p1 / 5.0;
1937
1938 assert_eq!(result, Point2D::new(3.0, 5.0));
1939 }
1940
1941 #[test]
1942 pub fn test_div_assign_scalar() {
1943 let mut p1: Point2D<f32> = Point2D::new(15.0, 25.0);
1944
1945 p1 /= 5.0;
1946
1947 assert_eq!(p1, Point2D::new(3.0, 5.0));
1948 }
1949
1950 #[test]
1951 pub fn test_div_scale() {
1952 let p1 = Point2DCm::new(0.1, 0.2);
1953 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
1954
1955 let result = p1 / cm_per_mm;
1956
1957 assert_eq!(result, Point2DMm::new(1.0, 2.0));
1958 }
1959
1960 #[test]
1961 pub fn test_div_assign_scale() {
1962 let mut p1 = Point2DMm::new(0.1, 0.2);
1963 let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
1964
1965 p1 /= scale;
1966
1967 assert_eq!(p1, Point2DMm::new(1.0, 2.0));
1968 }
1969
1970 #[test]
1971 pub fn test_point_debug_formatting() {
1972 let n = 1.23456789;
1973 let p1 = Point2D::new(n, -n);
1974 let should_be = format!("({:.4}, {:.4})", n, -n);
1975
1976 let got = format!("{:.4?}", p1);
1977
1978 assert_eq!(got, should_be);
1979 }
1980 }
1981
1982 mod euclid {
1983 use crate::default::{Point2D, Size2D};
1984 use crate::point2;
1985
1986 #[test]
1987 pub fn test_rem_euclid() {
1988 let p = Point2D::new(7.0, -7.0);
1989 let s = Size2D::new(4.0, -4.0);
1990
1991 assert_eq!(p.rem_euclid(&s), point2(3.0, 1.0));
1992 assert_eq!((-p).rem_euclid(&s), point2(1.0, 3.0));
1993 assert_eq!(p.rem_euclid(&-s), point2(3.0, 1.0));
1994 }
1995
1996 #[test]
1997 pub fn test_div_euclid() {
1998 let p = Point2D::new(7.0, -7.0);
1999 let s = Size2D::new(4.0, -4.0);
2000
2001 assert_eq!(p.div_euclid(&s), point2(1.0, 2.0));
2002 assert_eq!((-p).div_euclid(&s), point2(-2.0, -1.0));
2003 assert_eq!(p.div_euclid(&-s), point2(-1.0, -2.0));
2004 }
2005 }
2006}
2007
2008#[cfg(test)]
2009#[cfg(any(feature = "std", feature = "libm"))]
2010mod point3d {
2011 use crate::default;
2012 use crate::default::Point3D;
2013 use crate::{point2, point3};
2014 #[cfg(feature = "mint")]
2015 use mint;
2016
2017 #[test]
2018 pub fn test_min() {
2019 let p1 = Point3D::new(1.0, 3.0, 5.0);
2020 let p2 = Point3D::new(2.0, 2.0, -1.0);
2021
2022 let result = p1.min(p2);
2023
2024 assert_eq!(result, Point3D::new(1.0, 2.0, -1.0));
2025 }
2026
2027 #[test]
2028 pub fn test_max() {
2029 let p1 = Point3D::new(1.0, 3.0, 5.0);
2030 let p2 = Point3D::new(2.0, 2.0, -1.0);
2031
2032 let result = p1.max(p2);
2033
2034 assert_eq!(result, Point3D::new(2.0, 3.0, 5.0));
2035 }
2036
2037 #[test]
2038 pub fn test_conv_vector() {
2039 use crate::point3;
2040 for i in 0..100 {
2041 let x = i as f32 * 0.012345;
2043 let y = i as f32 * 0.987654;
2044 let z = x * y;
2045 let p: Point3D<f32> = point3(x, y, z);
2046 assert_eq!(p.to_vector().to_point(), p);
2047 }
2048 }
2049
2050 #[test]
2051 pub fn test_swizzling() {
2052 let p: default::Point3D<i32> = point3(1, 2, 3);
2053 assert_eq!(p.xy(), point2(1, 2));
2054 assert_eq!(p.xz(), point2(1, 3));
2055 assert_eq!(p.yz(), point2(2, 3));
2056 }
2057
2058 #[test]
2059 pub fn test_distance_to() {
2060 let p1 = Point3D::new(1.0, 2.0, 3.0);
2061 let p2 = Point3D::new(2.0, 2.0, 3.0);
2062
2063 assert_eq!(p1.distance_to(p2), 1.0);
2064
2065 let p1 = Point3D::new(1.0, 2.0, 3.0);
2066 let p2 = Point3D::new(1.0, 4.0, 3.0);
2067
2068 assert_eq!(p1.distance_to(p2), 2.0);
2069
2070 let p1 = Point3D::new(1.0, 2.0, 3.0);
2071 let p2 = Point3D::new(1.0, 2.0, 6.0);
2072
2073 assert_eq!(p1.distance_to(p2), 3.0);
2074 }
2075
2076 #[cfg(feature = "mint")]
2077 #[test]
2078 pub fn test_mint() {
2079 let p1 = Point3D::new(1.0, 3.0, 5.0);
2080 let pm: mint::Point3<_> = p1.into();
2081 let p2 = Point3D::from(pm);
2082
2083 assert_eq!(p1, p2);
2084 }
2085
2086 mod ops {
2087 use crate::default::Point3D;
2088 use crate::scale::Scale;
2089 use crate::{size3, vec3, Vector3D};
2090
2091 pub enum Mm {}
2092 pub enum Cm {}
2093
2094 pub type Point3DMm<T> = crate::Point3D<T, Mm>;
2095 pub type Point3DCm<T> = crate::Point3D<T, Cm>;
2096
2097 #[test]
2098 pub fn test_neg() {
2099 assert_eq!(-Point3D::new(1.0, 2.0, 3.0), Point3D::new(-1.0, -2.0, -3.0));
2100 assert_eq!(-Point3D::new(0.0, 0.0, 0.0), Point3D::new(-0.0, -0.0, -0.0));
2101 assert_eq!(-Point3D::new(-1.0, -2.0, -3.0), Point3D::new(1.0, 2.0, 3.0));
2102 }
2103
2104 #[test]
2105 pub fn test_add_size() {
2106 let p1 = Point3DMm::new(1.0, 2.0, 3.0);
2107 let p2 = size3(4.0, 5.0, 6.0);
2108
2109 let result = p1 + p2;
2110
2111 assert_eq!(result, Point3DMm::new(5.0, 7.0, 9.0));
2112 }
2113
2114 #[test]
2115 pub fn test_add_assign_size() {
2116 let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
2117
2118 p1 += size3(4.0, 5.0, 6.0);
2119
2120 assert_eq!(p1, Point3DMm::new(5.0, 7.0, 9.0));
2121 }
2122
2123 #[test]
2124 pub fn test_add_vec() {
2125 let p1 = Point3DMm::new(1.0, 2.0, 3.0);
2126 let p2 = vec3(4.0, 5.0, 6.0);
2127
2128 let result = p1 + p2;
2129
2130 assert_eq!(result, Point3DMm::new(5.0, 7.0, 9.0));
2131 }
2132
2133 #[test]
2134 pub fn test_add_assign_vec() {
2135 let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
2136
2137 p1 += vec3(4.0, 5.0, 6.0);
2138
2139 assert_eq!(p1, Point3DMm::new(5.0, 7.0, 9.0));
2140 }
2141
2142 #[test]
2143 pub fn test_sub() {
2144 let p1 = Point3DMm::new(1.0, 2.0, 3.0);
2145 let p2 = Point3DMm::new(4.0, 5.0, 6.0);
2146
2147 let result = p1 - p2;
2148
2149 assert_eq!(result, Vector3D::<_, Mm>::new(-3.0, -3.0, -3.0));
2150 }
2151
2152 #[test]
2153 pub fn test_sub_size() {
2154 let p1 = Point3DMm::new(1.0, 2.0, 3.0);
2155 let p2 = size3(4.0, 5.0, 6.0);
2156
2157 let result = p1 - p2;
2158
2159 assert_eq!(result, Point3DMm::new(-3.0, -3.0, -3.0));
2160 }
2161
2162 #[test]
2163 pub fn test_sub_assign_size() {
2164 let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
2165
2166 p1 -= size3(4.0, 5.0, 6.0);
2167
2168 assert_eq!(p1, Point3DMm::new(-3.0, -3.0, -3.0));
2169 }
2170
2171 #[test]
2172 pub fn test_sub_vec() {
2173 let p1 = Point3DMm::new(1.0, 2.0, 3.0);
2174 let p2 = vec3(4.0, 5.0, 6.0);
2175
2176 let result = p1 - p2;
2177
2178 assert_eq!(result, Point3DMm::new(-3.0, -3.0, -3.0));
2179 }
2180
2181 #[test]
2182 pub fn test_sub_assign_vec() {
2183 let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
2184
2185 p1 -= vec3(4.0, 5.0, 6.0);
2186
2187 assert_eq!(p1, Point3DMm::new(-3.0, -3.0, -3.0));
2188 }
2189
2190 #[test]
2191 pub fn test_mul_scalar() {
2192 let p1: Point3D<f32> = Point3D::new(3.0, 5.0, 7.0);
2193
2194 let result = p1 * 5.0;
2195
2196 assert_eq!(result, Point3D::new(15.0, 25.0, 35.0));
2197 }
2198
2199 #[test]
2200 pub fn test_mul_assign_scalar() {
2201 let mut p1: Point3D<f32> = Point3D::new(3.0, 5.0, 7.0);
2202
2203 p1 *= 5.0;
2204
2205 assert_eq!(p1, Point3D::new(15.0, 25.0, 35.0));
2206 }
2207
2208 #[test]
2209 pub fn test_mul_scale() {
2210 let p1 = Point3DMm::new(1.0, 2.0, 3.0);
2211 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
2212
2213 let result = p1 * cm_per_mm;
2214
2215 assert_eq!(result, Point3DCm::new(0.1, 0.2, 0.3));
2216 }
2217
2218 #[test]
2219 pub fn test_mul_assign_scale() {
2220 let mut p1 = Point3DMm::new(1.0, 2.0, 3.0);
2221 let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
2222
2223 p1 *= scale;
2224
2225 assert_eq!(p1, Point3DMm::new(0.1, 0.2, 0.3));
2226 }
2227
2228 #[test]
2229 pub fn test_div_scalar() {
2230 let p1: Point3D<f32> = Point3D::new(15.0, 25.0, 35.0);
2231
2232 let result = p1 / 5.0;
2233
2234 assert_eq!(result, Point3D::new(3.0, 5.0, 7.0));
2235 }
2236
2237 #[test]
2238 pub fn test_div_assign_scalar() {
2239 let mut p1: Point3D<f32> = Point3D::new(15.0, 25.0, 35.0);
2240
2241 p1 /= 5.0;
2242
2243 assert_eq!(p1, Point3D::new(3.0, 5.0, 7.0));
2244 }
2245
2246 #[test]
2247 pub fn test_div_scale() {
2248 let p1 = Point3DCm::new(0.1, 0.2, 0.3);
2249 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
2250
2251 let result = p1 / cm_per_mm;
2252
2253 assert_eq!(result, Point3DMm::new(1.0, 2.0, 3.0));
2254 }
2255
2256 #[test]
2257 pub fn test_div_assign_scale() {
2258 let mut p1 = Point3DMm::new(0.1, 0.2, 0.3);
2259 let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
2260
2261 p1 /= scale;
2262
2263 assert_eq!(p1, Point3DMm::new(1.0, 2.0, 3.0));
2264 }
2265 }
2266
2267 mod euclid {
2268 use crate::default::{Point3D, Size3D};
2269 use crate::point3;
2270
2271 #[test]
2272 pub fn test_rem_euclid() {
2273 let p = Point3D::new(7.0, -7.0, 0.0);
2274 let s = Size3D::new(4.0, -4.0, 12.0);
2275
2276 assert_eq!(p.rem_euclid(&s), point3(3.0, 1.0, 0.0));
2277 assert_eq!((-p).rem_euclid(&s), point3(1.0, 3.0, 0.0));
2278 assert_eq!(p.rem_euclid(&-s), point3(3.0, 1.0, 0.0));
2279 }
2280
2281 #[test]
2282 pub fn test_div_euclid() {
2283 let p = Point3D::new(7.0, -7.0, 0.0);
2284 let s = Size3D::new(4.0, -4.0, 12.0);
2285
2286 assert_eq!(p.div_euclid(&s), point3(1.0, 2.0, 0.0));
2287 assert_eq!((-p).div_euclid(&s), point3(-2.0, -1.0, 0.0));
2288 assert_eq!(p.div_euclid(&-s), point3(-1.0, -2.0, 0.0));
2289 }
2290 }
2291}