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