1use super::UnknownUnit;
11use approxeq::ApproxEq;
12use length::Length;
13use scale::TypedScale;
14use size::{TypedSize2D, TypedSize3D};
15#[cfg(feature = "mint")]
16use mint;
17use num::*;
18use num_traits::{Float, NumCast};
19use vector::{TypedVector2D, TypedVector3D, vec2, vec3};
20use core::fmt;
21use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
22use core::marker::PhantomData;
23
24#[derive(EuclidMatrix)]
26#[repr(C)]
27pub struct TypedPoint2D<T, U> {
28 pub x: T,
29 pub y: T,
30 #[doc(hidden)]
31 pub _unit: PhantomData<U>,
32}
33
34mint_vec!(TypedPoint2D[x, y] = Point2);
35
36pub type Point2D<T> = TypedPoint2D<T, UnknownUnit>;
40
41impl<T: Copy + Zero, U> TypedPoint2D<T, U> {
42 #[inline]
44 pub fn origin() -> Self {
45 point2(Zero::zero(), Zero::zero())
46 }
47
48 #[inline]
49 pub fn zero() -> Self {
50 Self::origin()
51 }
52
53 #[inline]
55 pub fn to_3d(&self) -> TypedPoint3D<T, U> {
56 point3(self.x, self.y, Zero::zero())
57 }
58}
59
60impl<T: fmt::Debug, U> fmt::Debug for TypedPoint2D<T, U> {
61 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
62 write!(f, "({:?},{:?})", self.x, self.y)
63 }
64}
65
66impl<T: fmt::Display, U> fmt::Display for TypedPoint2D<T, U> {
67 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
68 write!(formatter, "({},{})", self.x, self.y)
69 }
70}
71
72impl<T: Default, U> Default for TypedPoint2D<T, U> {
73 fn default() -> Self {
74 TypedPoint2D::new(Default::default(), Default::default())
75 }
76}
77
78impl<T, U> TypedPoint2D<T, U> {
79 #[inline]
81 pub fn new(x: T, y: T) -> Self {
82 TypedPoint2D {
83 x,
84 y,
85 _unit: PhantomData,
86 }
87 }
88}
89
90impl<T: Copy, U> TypedPoint2D<T, U> {
91 #[inline]
93 pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self {
94 point2(x.0, y.0)
95 }
96
97 #[inline]
99 pub fn extend(&self, z: T) -> TypedPoint3D<T, U> {
100 point3(self.x, self.y, z)
101 }
102
103 #[inline]
107 pub fn to_vector(&self) -> TypedVector2D<T, U> {
108 vec2(self.x, self.y)
109 }
110
111 #[inline]
113 pub fn yx(&self) -> Self {
114 point2(self.y, self.x)
115 }
116
117 #[inline]
119 pub fn x_typed(&self) -> Length<T, U> {
120 Length::new(self.x)
121 }
122
123 #[inline]
125 pub fn y_typed(&self) -> Length<T, U> {
126 Length::new(self.y)
127 }
128
129 #[inline]
131 pub fn to_untyped(&self) -> Point2D<T> {
132 point2(self.x, self.y)
133 }
134
135 #[inline]
137 pub fn from_untyped(p: &Point2D<T>) -> Self {
138 point2(p.x, p.y)
139 }
140
141 #[inline]
142 pub fn to_array(&self) -> [T; 2] {
143 [self.x, self.y]
144 }
145
146 #[inline]
147 pub fn to_tuple(&self) -> (T, T) {
148 (self.x, self.y)
149 }
150}
151
152impl<T: Copy + Add<T, Output = T>, U> TypedPoint2D<T, U> {
153 #[inline]
154 pub fn add_size(&self, other: &TypedSize2D<T, U>) -> Self {
155 point2(self.x + other.width, self.y + other.height)
156 }
157}
158
159impl<T: Copy + Add<T, Output = T>, U> Add<TypedSize2D<T, U>> for TypedPoint2D<T, U> {
160 type Output = Self;
161 #[inline]
162 fn add(self, other: TypedSize2D<T, U>) -> Self {
163 point2(self.x + other.width, self.y + other.height)
164 }
165}
166
167impl<T: Copy + Add<T, Output = T>, U> AddAssign<TypedVector2D<T, U>> for TypedPoint2D<T, U> {
168 #[inline]
169 fn add_assign(&mut self, other: TypedVector2D<T, U>) {
170 *self = *self + other
171 }
172}
173
174impl<T: Copy + Sub<T, Output = T>, U> SubAssign<TypedVector2D<T, U>> for TypedPoint2D<T, U> {
175 #[inline]
176 fn sub_assign(&mut self, other: TypedVector2D<T, U>) {
177 *self = *self - other
178 }
179}
180
181impl<T: Copy + Add<T, Output = T>, U> Add<TypedVector2D<T, U>> for TypedPoint2D<T, U> {
182 type Output = Self;
183 #[inline]
184 fn add(self, other: TypedVector2D<T, U>) -> Self {
185 point2(self.x + other.x, self.y + other.y)
186 }
187}
188
189impl<T: Copy + Sub<T, Output = T>, U> Sub for TypedPoint2D<T, U> {
190 type Output = TypedVector2D<T, U>;
191 #[inline]
192 fn sub(self, other: Self) -> TypedVector2D<T, U> {
193 vec2(self.x - other.x, self.y - other.y)
194 }
195}
196
197impl<T: Copy + Sub<T, Output = T>, U> Sub<TypedVector2D<T, U>> for TypedPoint2D<T, U> {
198 type Output = Self;
199 #[inline]
200 fn sub(self, other: TypedVector2D<T, U>) -> Self {
201 point2(self.x - other.x, self.y - other.y)
202 }
203}
204
205impl<T: Float, U> TypedPoint2D<T, U> {
206 #[inline]
207 pub fn min(self, other: Self) -> Self {
208 point2(self.x.min(other.x), self.y.min(other.y))
209 }
210
211 #[inline]
212 pub fn max(self, other: Self) -> Self {
213 point2(self.x.max(other.x), self.y.max(other.y))
214 }
215
216 #[inline]
217 pub fn clamp(&self, start: Self, end: Self) -> Self {
218 self.max(start).min(end)
219 }
220}
221
222impl<T: Copy + Mul<T, Output = T>, U> Mul<T> for TypedPoint2D<T, U> {
223 type Output = Self;
224 #[inline]
225 fn mul(self, scale: T) -> Self {
226 point2(self.x * scale, self.y * scale)
227 }
228}
229
230impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for TypedPoint2D<T, U> {
231 #[inline]
232 fn mul_assign(&mut self, scale: T) {
233 *self = *self * scale
234 }
235}
236
237impl<T: Copy + Div<T, Output = T>, U> Div<T> for TypedPoint2D<T, U> {
238 type Output = Self;
239 #[inline]
240 fn div(self, scale: T) -> Self {
241 point2(self.x / scale, self.y / scale)
242 }
243}
244
245impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for TypedPoint2D<T, U> {
246 #[inline]
247 fn div_assign(&mut self, scale: T) {
248 *self = *self / scale
249 }
250}
251
252impl<T: Copy + Mul<T, Output = T>, U1, U2> Mul<TypedScale<T, U1, U2>> for TypedPoint2D<T, U1> {
253 type Output = TypedPoint2D<T, U2>;
254 #[inline]
255 fn mul(self, scale: TypedScale<T, U1, U2>) -> TypedPoint2D<T, U2> {
256 point2(self.x * scale.get(), self.y * scale.get())
257 }
258}
259
260impl<T: Copy + Div<T, Output = T>, U1, U2> Div<TypedScale<T, U1, U2>> for TypedPoint2D<T, U2> {
261 type Output = TypedPoint2D<T, U1>;
262 #[inline]
263 fn div(self, scale: TypedScale<T, U1, U2>) -> TypedPoint2D<T, U1> {
264 point2(self.x / scale.get(), self.y / scale.get())
265 }
266}
267
268impl<T: Round, U> TypedPoint2D<T, U> {
269 #[inline]
274 #[cfg_attr(feature = "unstable", must_use)]
275 pub fn round(&self) -> Self {
276 point2(self.x.round(), self.y.round())
277 }
278}
279
280impl<T: Ceil, U> TypedPoint2D<T, U> {
281 #[inline]
286 #[cfg_attr(feature = "unstable", must_use)]
287 pub fn ceil(&self) -> Self {
288 point2(self.x.ceil(), self.y.ceil())
289 }
290}
291
292impl<T: Floor, U> TypedPoint2D<T, U> {
293 #[inline]
298 #[cfg_attr(feature = "unstable", must_use)]
299 pub fn floor(&self) -> Self {
300 point2(self.x.floor(), self.y.floor())
301 }
302}
303
304impl<T: NumCast + Copy, U> TypedPoint2D<T, U> {
305 #[inline]
311 pub fn cast<NewT: NumCast + Copy>(&self) -> TypedPoint2D<NewT, U> {
312 self.try_cast().unwrap()
313 }
314
315 pub fn try_cast<NewT: NumCast + Copy>(&self) -> Option<TypedPoint2D<NewT, U>> {
321 match (NumCast::from(self.x), NumCast::from(self.y)) {
322 (Some(x), Some(y)) => Some(point2(x, y)),
323 _ => None,
324 }
325 }
326
327 #[inline]
331 pub fn to_f32(&self) -> TypedPoint2D<f32, U> {
332 self.cast()
333 }
334
335 #[inline]
337 pub fn to_f64(&self) -> TypedPoint2D<f64, U> {
338 self.cast()
339 }
340
341 #[inline]
347 pub fn to_usize(&self) -> TypedPoint2D<usize, U> {
348 self.cast()
349 }
350
351 #[inline]
357 pub fn to_u32(&self) -> TypedPoint2D<u32, U> {
358 self.cast()
359 }
360
361 #[inline]
367 pub fn to_i32(&self) -> TypedPoint2D<i32, U> {
368 self.cast()
369 }
370
371 #[inline]
377 pub fn to_i64(&self) -> TypedPoint2D<i64, U> {
378 self.cast()
379 }
380}
381
382impl<T, U> TypedPoint2D<T, U>
383where
384 T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
385{
386 #[inline]
390 pub fn lerp(&self, other: Self, t: T) -> Self {
391 let one_t = T::one() - t;
392 point2(one_t * self.x + t * other.x, one_t * self.y + t * other.y)
393 }
394}
395
396impl<T: Copy + ApproxEq<T>, U> ApproxEq<TypedPoint2D<T, U>> for TypedPoint2D<T, U> {
397 #[inline]
398 fn approx_epsilon() -> Self {
399 point2(T::approx_epsilon(), T::approx_epsilon())
400 }
401
402 #[inline]
403 fn approx_eq(&self, other: &Self) -> bool {
404 self.x.approx_eq(&other.x) && self.y.approx_eq(&other.y)
405 }
406
407 #[inline]
408 fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
409 self.x.approx_eq_eps(&other.x, &eps.x) && self.y.approx_eq_eps(&other.y, &eps.y)
410 }
411}
412
413impl<T: Copy, U> Into<[T; 2]> for TypedPoint2D<T, U> {
414 fn into(self) -> [T; 2] {
415 self.to_array()
416 }
417}
418
419impl<T: Copy, U> From<[T; 2]> for TypedPoint2D<T, U> {
420 fn from(array: [T; 2]) -> Self {
421 point2(array[0], array[1])
422 }
423}
424
425impl<T: Copy, U> Into<(T, T)> for TypedPoint2D<T, U> {
426 fn into(self) -> (T, T) {
427 self.to_tuple()
428 }
429}
430
431impl<T: Copy, U> From<(T, T)> for TypedPoint2D<T, U> {
432 fn from(tuple: (T, T)) -> Self {
433 point2(tuple.0, tuple.1)
434 }
435}
436
437#[derive(EuclidMatrix)]
439#[repr(C)]
440pub struct TypedPoint3D<T, U> {
441 pub x: T,
442 pub y: T,
443 pub z: T,
444 #[doc(hidden)]
445 pub _unit: PhantomData<U>,
446}
447
448mint_vec!(TypedPoint3D[x, y, z] = Point3);
449
450pub type Point3D<T> = TypedPoint3D<T, UnknownUnit>;
454
455impl<T: Copy + Zero, U> TypedPoint3D<T, U> {
456 #[inline]
458 pub fn origin() -> Self {
459 point3(Zero::zero(), Zero::zero(), Zero::zero())
460 }
461
462 #[inline]
463 pub fn zero() -> Self {
464 Self::origin()
465 }
466}
467
468impl<T: Copy + One, U> TypedPoint3D<T, U> {
469 #[inline]
470 pub fn to_array_4d(&self) -> [T; 4] {
471 [self.x, self.y, self.z, One::one()]
472 }
473
474 #[inline]
475 pub fn to_tuple_4d(&self) -> (T, T, T, T) {
476 (self.x, self.y, self.z, One::one())
477 }
478}
479
480impl<T, U> TypedPoint3D<T, U>
481where
482 T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
483{
484 #[inline]
488 pub fn lerp(&self, other: Self, t: T) -> Self {
489 let one_t = T::one() - t;
490 point3(
491 one_t * self.x + t * other.x,
492 one_t * self.y + t * other.y,
493 one_t * self.z + t * other.z,
494 )
495 }
496}
497
498impl<T: fmt::Debug, U> fmt::Debug for TypedPoint3D<T, U> {
499 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
500 write!(f, "({:?},{:?},{:?})", self.x, self.y, self.z)
501 }
502}
503
504impl<T: fmt::Display, U> fmt::Display for TypedPoint3D<T, U> {
505 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
506 write!(f, "({},{},{})", self.x, self.y, self.z)
507 }
508}
509
510impl<T: Copy + Default, U> Default for TypedPoint3D<T, U> {
511 fn default() -> Self {
512 TypedPoint3D::new(Default::default(), Default::default(), Default::default())
513 }
514}
515
516impl<T: Copy, U> TypedPoint3D<T, U> {
517 #[inline]
519 pub fn new(x: T, y: T, z: T) -> Self {
520 TypedPoint3D {
521 x,
522 y,
523 z,
524 _unit: PhantomData,
525 }
526 }
527
528 #[inline]
530 pub fn from_lengths(x: Length<T, U>, y: Length<T, U>, z: Length<T, U>) -> Self {
531 point3(x.0, y.0, z.0)
532 }
533
534 #[inline]
538 pub fn to_vector(&self) -> TypedVector3D<T, U> {
539 vec3(self.x, self.y, self.z)
540 }
541
542 #[inline]
544 pub fn xy(&self) -> TypedPoint2D<T, U> {
545 point2(self.x, self.y)
546 }
547
548 #[inline]
550 pub fn xz(&self) -> TypedPoint2D<T, U> {
551 point2(self.x, self.z)
552 }
553
554 #[inline]
556 pub fn yz(&self) -> TypedPoint2D<T, U> {
557 point2(self.y, self.z)
558 }
559
560 #[inline]
562 pub fn x_typed(&self) -> Length<T, U> {
563 Length::new(self.x)
564 }
565
566 #[inline]
568 pub fn y_typed(&self) -> Length<T, U> {
569 Length::new(self.y)
570 }
571
572 #[inline]
574 pub fn z_typed(&self) -> Length<T, U> {
575 Length::new(self.z)
576 }
577
578 #[inline]
579 pub fn to_array(&self) -> [T; 3] {
580 [self.x, self.y, self.z]
581 }
582
583 #[inline]
584 pub fn to_tuple(&self) -> (T, T, T) {
585 (self.x, self.y, self.z)
586 }
587
588 #[inline]
590 pub fn to_untyped(&self) -> Point3D<T> {
591 point3(self.x, self.y, self.z)
592 }
593
594 #[inline]
596 pub fn from_untyped(p: &Point3D<T>) -> Self {
597 point3(p.x, p.y, p.z)
598 }
599
600 #[inline]
602 pub fn to_2d(&self) -> TypedPoint2D<T, U> {
603 self.xy()
604 }
605}
606
607impl<T: Copy + Add<T, Output = T>, U> TypedPoint3D<T, U> {
608 #[inline]
609 pub fn add_size(&self, other: &TypedSize3D<T, U>) -> Self {
610 point3(self.x + other.width, self.y + other.height, self.z + other.depth)
611 }
612}
613
614impl<T: Copy + Add<T, Output = T>, U> AddAssign<TypedVector3D<T, U>> for TypedPoint3D<T, U> {
615 #[inline]
616 fn add_assign(&mut self, other: TypedVector3D<T, U>) {
617 *self = *self + other
618 }
619}
620
621impl<T: Copy + Sub<T, Output = T>, U> SubAssign<TypedVector3D<T, U>> for TypedPoint3D<T, U> {
622 #[inline]
623 fn sub_assign(&mut self, other: TypedVector3D<T, U>) {
624 *self = *self - other
625 }
626}
627
628impl<T: Copy + Add<T, Output = T>, U> Add<TypedVector3D<T, U>> for TypedPoint3D<T, U> {
629 type Output = Self;
630 #[inline]
631 fn add(self, other: TypedVector3D<T, U>) -> Self {
632 point3(self.x + other.x, self.y + other.y, self.z + other.z)
633 }
634}
635
636impl<T: Copy + Sub<T, Output = T>, U> Sub for TypedPoint3D<T, U> {
637 type Output = TypedVector3D<T, U>;
638 #[inline]
639 fn sub(self, other: Self) -> TypedVector3D<T, U> {
640 vec3(self.x - other.x, self.y - other.y, self.z - other.z)
641 }
642}
643
644impl<T: Copy + Sub<T, Output = T>, U> Sub<TypedVector3D<T, U>> for TypedPoint3D<T, U> {
645 type Output = Self;
646 #[inline]
647 fn sub(self, other: TypedVector3D<T, U>) -> Self {
648 point3(self.x - other.x, self.y - other.y, self.z - other.z)
649 }
650}
651
652impl<T: Copy + Mul<T, Output = T>, U> Mul<T> for TypedPoint3D<T, U> {
653 type Output = Self;
654 #[inline]
655 fn mul(self, scale: T) -> Self {
656 point3(self.x * scale, self.y * scale, self.z * scale)
657 }
658}
659
660impl<T: Copy + Mul<T, Output = T>, U1, U2> Mul<TypedScale<T, U1, U2>> for TypedPoint3D<T, U1> {
661 type Output = TypedPoint3D<T, U2>;
662 #[inline]
663 fn mul(self, scale: TypedScale<T, U1, U2>) -> TypedPoint3D<T, U2> {
664 point3(self.x * scale.get(), self.y * scale.get(), self.z * scale.get())
665 }
666}
667
668impl<T: Copy + Div<T, Output = T>, U> Div<T> for TypedPoint3D<T, U> {
669 type Output = Self;
670 #[inline]
671 fn div(self, scale: T) -> Self {
672 point3(self.x / scale, self.y / scale, self.z / scale)
673 }
674}
675
676impl<T: Copy + Div<T, Output = T>, U1, U2> Div<TypedScale<T, U1, U2>> for TypedPoint3D<T, U2> {
677 type Output = TypedPoint3D<T, U1>;
678 #[inline]
679 fn div(self, scale: TypedScale<T, U1, U2>) -> TypedPoint3D<T, U1> {
680 point3(self.x / scale.get(), self.y / scale.get(), self.z / scale.get())
681 }
682}
683
684impl<T: Float, U> TypedPoint3D<T, U> {
685 #[inline]
686 pub fn min(self, other: Self) -> Self {
687 point3(
688 self.x.min(other.x),
689 self.y.min(other.y),
690 self.z.min(other.z),
691 )
692 }
693
694 #[inline]
695 pub fn max(self, other: Self) -> Self {
696 point3(
697 self.x.max(other.x),
698 self.y.max(other.y),
699 self.z.max(other.z),
700 )
701 }
702
703 #[inline]
704 pub fn clamp(&self, start: Self, end: Self) -> Self {
705 self.max(start).min(end)
706 }
707}
708
709impl<T: Round, U> TypedPoint3D<T, U> {
710 #[inline]
714 #[cfg_attr(feature = "unstable", must_use)]
715 pub fn round(&self) -> Self {
716 point3(self.x.round(), self.y.round(), self.z.round())
717 }
718}
719
720impl<T: Ceil, U> TypedPoint3D<T, U> {
721 #[inline]
725 #[cfg_attr(feature = "unstable", must_use)]
726 pub fn ceil(&self) -> Self {
727 point3(self.x.ceil(), self.y.ceil(), self.z.ceil())
728 }
729}
730
731impl<T: Floor, U> TypedPoint3D<T, U> {
732 #[inline]
736 #[cfg_attr(feature = "unstable", must_use)]
737 pub fn floor(&self) -> Self {
738 point3(self.x.floor(), self.y.floor(), self.z.floor())
739 }
740}
741
742impl<T: NumCast + Copy, U> TypedPoint3D<T, U> {
743 #[inline]
749 pub fn cast<NewT: NumCast + Copy>(&self) -> TypedPoint3D<NewT, U> {
750 self.try_cast().unwrap()
751 }
752
753 #[inline]
759 pub fn try_cast<NewT: NumCast + Copy>(&self) -> Option<TypedPoint3D<NewT, U>> {
760 match (
761 NumCast::from(self.x),
762 NumCast::from(self.y),
763 NumCast::from(self.z),
764 ) {
765 (Some(x), Some(y), Some(z)) => Some(point3(x, y, z)),
766 _ => None,
767 }
768 }
769
770 #[inline]
774 pub fn to_f32(&self) -> TypedPoint3D<f32, U> {
775 self.cast()
776 }
777
778 #[inline]
780 pub fn to_f64(&self) -> TypedPoint3D<f64, U> {
781 self.cast()
782 }
783
784 #[inline]
790 pub fn to_usize(&self) -> TypedPoint3D<usize, U> {
791 self.cast()
792 }
793
794 #[inline]
800 pub fn to_u32(&self) -> TypedPoint3D<u32, U> {
801 self.cast()
802 }
803
804 #[inline]
810 pub fn to_i32(&self) -> TypedPoint3D<i32, U> {
811 self.cast()
812 }
813
814 #[inline]
820 pub fn to_i64(&self) -> TypedPoint3D<i64, U> {
821 self.cast()
822 }
823}
824
825impl<T: Copy + ApproxEq<T>, U> ApproxEq<TypedPoint3D<T, U>> for TypedPoint3D<T, U> {
826 #[inline]
827 fn approx_epsilon() -> Self {
828 point3(
829 T::approx_epsilon(),
830 T::approx_epsilon(),
831 T::approx_epsilon(),
832 )
833 }
834
835 #[inline]
836 fn approx_eq(&self, other: &Self) -> bool {
837 self.x.approx_eq(&other.x) && self.y.approx_eq(&other.y) && self.z.approx_eq(&other.z)
838 }
839
840 #[inline]
841 fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
842 self.x.approx_eq_eps(&other.x, &eps.x) && self.y.approx_eq_eps(&other.y, &eps.y)
843 && self.z.approx_eq_eps(&other.z, &eps.z)
844 }
845}
846
847impl<T: Copy, U> Into<[T; 3]> for TypedPoint3D<T, U> {
848 fn into(self) -> [T; 3] {
849 self.to_array()
850 }
851}
852
853impl<T: Copy, U> From<[T; 3]> for TypedPoint3D<T, U> {
854 fn from(array: [T; 3]) -> Self {
855 point3(array[0], array[1], array[2])
856 }
857}
858
859impl<T: Copy, U> Into<(T, T, T)> for TypedPoint3D<T, U> {
860 fn into(self) -> (T, T, T) {
861 self.to_tuple()
862 }
863}
864
865impl<T: Copy, U> From<(T, T, T)> for TypedPoint3D<T, U> {
866 fn from(tuple: (T, T, T)) -> Self {
867 point3(tuple.0, tuple.1, tuple.2)
868 }
869}
870
871pub fn point2<T: Copy, U>(x: T, y: T) -> TypedPoint2D<T, U> {
872 TypedPoint2D::new(x, y)
873}
874
875pub fn point3<T: Copy, U>(x: T, y: T, z: T) -> TypedPoint3D<T, U> {
876 TypedPoint3D::new(x, y, z)
877}
878
879
880#[cfg(test)]
881mod point2d {
882 use super::Point2D;
883 #[cfg(feature = "mint")]
884 use mint;
885
886 #[test]
887 pub fn test_scalar_mul() {
888 let p1: Point2D<f32> = Point2D::new(3.0, 5.0);
889
890 let result = p1 * 5.0;
891
892 assert_eq!(result, Point2D::new(15.0, 25.0));
893 }
894
895 #[test]
896 pub fn test_min() {
897 let p1 = Point2D::new(1.0, 3.0);
898 let p2 = Point2D::new(2.0, 2.0);
899
900 let result = p1.min(p2);
901
902 assert_eq!(result, Point2D::new(1.0, 2.0));
903 }
904
905 #[test]
906 pub fn test_max() {
907 let p1 = Point2D::new(1.0, 3.0);
908 let p2 = Point2D::new(2.0, 2.0);
909
910 let result = p1.max(p2);
911
912 assert_eq!(result, Point2D::new(2.0, 3.0));
913 }
914
915 #[cfg(feature = "mint")]
916 #[test]
917 pub fn test_mint() {
918 let p1 = Point2D::new(1.0, 3.0);
919 let pm: mint::Point2<_> = p1.into();
920 let p2 = Point2D::from(pm);
921
922 assert_eq!(p1, p2);
923 }
924}
925
926#[cfg(test)]
927mod typedpoint2d {
928 use super::{Point2D, TypedPoint2D, point2};
929 use scale::TypedScale;
930 use vector::vec2;
931
932 pub enum Mm {}
933 pub enum Cm {}
934
935 pub type Point2DMm<T> = TypedPoint2D<T, Mm>;
936 pub type Point2DCm<T> = TypedPoint2D<T, Cm>;
937
938 #[test]
939 pub fn test_add() {
940 let p1 = Point2DMm::new(1.0, 2.0);
941 let p2 = vec2(3.0, 4.0);
942
943 let result = p1 + p2;
944
945 assert_eq!(result, Point2DMm::new(4.0, 6.0));
946 }
947
948 #[test]
949 pub fn test_add_assign() {
950 let mut p1 = Point2DMm::new(1.0, 2.0);
951 p1 += vec2(3.0, 4.0);
952
953 assert_eq!(p1, Point2DMm::new(4.0, 6.0));
954 }
955
956 #[test]
957 pub fn test_scalar_mul() {
958 let p1 = Point2DMm::new(1.0, 2.0);
959 let cm_per_mm: TypedScale<f32, Mm, Cm> = TypedScale::new(0.1);
960
961 let result = p1 * cm_per_mm;
962
963 assert_eq!(result, Point2DCm::new(0.1, 0.2));
964 }
965
966 #[test]
967 pub fn test_conv_vector() {
968 use {Point2D, point2};
969
970 for i in 0..100 {
971 let x = i as f32 * 0.012345;
973 let y = i as f32 * 0.987654;
974 let p: Point2D<f32> = point2(x, y);
975 assert_eq!(p.to_vector().to_point(), p);
976 }
977 }
978
979 #[test]
980 pub fn test_swizzling() {
981 let p: Point2D<i32> = point2(1, 2);
982 assert_eq!(p.yx(), point2(2, 1));
983 }
984}
985
986#[cfg(test)]
987mod point3d {
988 use super::{Point3D, point2, point3};
989 #[cfg(feature = "mint")]
990 use mint;
991
992 #[test]
993 pub fn test_min() {
994 let p1 = Point3D::new(1.0, 3.0, 5.0);
995 let p2 = Point3D::new(2.0, 2.0, -1.0);
996
997 let result = p1.min(p2);
998
999 assert_eq!(result, Point3D::new(1.0, 2.0, -1.0));
1000 }
1001
1002 #[test]
1003 pub fn test_max() {
1004 let p1 = Point3D::new(1.0, 3.0, 5.0);
1005 let p2 = Point3D::new(2.0, 2.0, -1.0);
1006
1007 let result = p1.max(p2);
1008
1009 assert_eq!(result, Point3D::new(2.0, 3.0, 5.0));
1010 }
1011
1012 #[test]
1013 pub fn test_conv_vector() {
1014 use point3;
1015 for i in 0..100 {
1016 let x = i as f32 * 0.012345;
1018 let y = i as f32 * 0.987654;
1019 let z = x * y;
1020 let p: Point3D<f32> = point3(x, y, z);
1021 assert_eq!(p.to_vector().to_point(), p);
1022 }
1023 }
1024
1025 #[test]
1026 pub fn test_swizzling() {
1027 let p: Point3D<i32> = point3(1, 2, 3);
1028 assert_eq!(p.xy(), point2(1, 2));
1029 assert_eq!(p.xz(), point2(1, 3));
1030 assert_eq!(p.yz(), point2(2, 3));
1031 }
1032
1033 #[cfg(feature = "mint")]
1034 #[test]
1035 pub fn test_mint() {
1036 let p1 = Point3D::new(1.0, 3.0, 5.0);
1037 let pm: mint::Point3<_> = p1.into();
1038 let p2 = Point3D::from(pm);
1039
1040 assert_eq!(p1, p2);
1041 }
1042
1043}