1pub use self::simplex2::Simplex2;
2pub use self::simplex3::Simplex3;
3
4pub mod simplex2 {
6 #[cfg(feature = "derive_serdes")]
7 use serde::{Deserialize, Serialize};
8
9 use crate::*;
10 use crate::geometry::*;
11
12 pub type SegmentPoint <S> = (Normalized <S>, Point2 <S>);
14 pub type TrianglePoint <S> = ([Normalized <S>; 2], Point2 <S>);
16
17 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
22 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
23 pub enum Simplex2 <S> {
24 Segment (Segment <S>),
25 Triangle (Triangle <S>)
26 }
27
28 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
32 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
33 pub struct Segment <S> {
34 a : Point2 <S>,
35 b : Point2 <S>
36 }
37
38 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
42 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
43 pub struct Triangle <S> {
44 a : Point2 <S>,
45 b : Point2 <S>,
46 c : Point2 <S>
47 }
48
49 impl <S : OrderedRing> Segment <S> {
50 pub fn new (a : Point2 <S>, b : Point2 <S>) -> Option <Self> {
57 if a == b {
58 None
59 } else {
60 Some (Segment { a, b })
61 }
62 }
63 pub fn noisy (a : Point2 <S>, b : Point2 <S>) -> Self {
70 assert_ne!(a, b);
71 Segment { a, b }
72 }
73 pub fn unchecked (a : Point2 <S>, b : Point2 <S>) -> Self {
80 debug_assert_ne!(a, b);
81 Segment { a, b }
82 }
83 #[inline]
84 pub fn from_array ([a, b] : [Point2 <S>; 2]) -> Option <Self> {
85 Self::new (a, b)
86 }
87 #[inline]
88 pub fn numcast <T> (self) -> Option <Segment <T>> where
89 S : num::NumCast,
90 T : num::NumCast
91 {
92 Some (Segment {
93 a: self.a.numcast()?,
94 b: self.b.numcast()?
95 })
96 }
97 #[inline]
98 pub const fn point_a (self) -> Point2 <S> {
99 self.a
100 }
101 #[inline]
102 pub const fn point_b (self) -> Point2 <S> {
103 self.b
104 }
105 #[inline]
106 pub const fn points (self) -> [Point2 <S>; 2] {
107 [self.a, self.b]
108 }
109 pub fn point (self, param : Normalized <S>) -> Point2 <S> {
111 self.a + *self.vector() * *param
112 }
113 #[inline]
114 pub fn length (self) -> NonNegative <S> where S : Field + Sqrt {
115 self.vector().norm()
116 }
117 #[inline]
118 pub fn length_squared (self) -> NonNegative <S> {
119 self.vector().self_dot()
120 }
121 #[inline]
123 pub fn vector (self) -> NonZero2 <S> {
124 NonZero2::unchecked (self.b - self.a)
125 }
126 #[inline]
127 pub fn perpendicular (self) -> NonZero2 <S> {
128 self.vector().map_unchecked (Vector2::yx)
129 }
130 #[inline]
131 pub fn translate (&mut self, displacement : Vector2 <S>) {
132 self.a += displacement;
133 self.b += displacement;
134 }
135 #[inline]
136 pub fn midpoint (self) -> Point2 <S> where S : Field {
137 ((self.a.0 + self.b.0) * S::half()).into()
138 }
139 #[inline]
140 pub fn aabb2 (self) -> Aabb2 <S> {
141 Aabb2::from_points_unchecked (self.a, self.b)
142 }
143 #[inline]
144 pub fn line (self) -> Line2 <S> where S : Real {
145 Line2::new (self.a, self.vector().normalize())
146 }
147 pub fn affine_line (self) -> frame::Line2 <S> {
148 frame::Line2 {
149 origin: self.a,
150 basis: self.vector()
151 }
152 }
153 #[inline]
154 pub fn nearest_point (self, point : Point2 <S>) -> SegmentPoint <S> where
155 S : Field
156 {
157 distance::nearest_segment2_point2 (self, point)
158 }
159 #[inline]
160 pub fn intersect_aabb (self, aabb : Aabb2 <S>)
161 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
162 where S : Real {
163 intersect::continuous_segment2_aabb2 (self, aabb)
164 }
165 #[inline]
166 pub fn intersect_sphere (self, sphere : Sphere2 <S>)
167 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
168 where S : Real {
169 intersect::continuous_segment2_sphere2 (self, sphere)
170 }
171 }
172 impl <S : Ring> Default for Segment <S> {
173 fn default() -> Self {
184 Segment {
185 a: [-S::one(), S::zero()].into(),
186 b: [ S::one(), S::zero()].into()
187 }
188 }
189 }
190 impl <S> std::ops::Index <usize> for Segment <S> where S : Copy {
191 type Output = Point2 <S>;
192 fn index (&self, index : usize) -> &Point2 <S> {
193 [&self.a, &self.b][index]
194 }
195 }
196 impl <S> TryFrom <[Point2 <S>; 2]> for Segment <S> where S : OrderedRing {
197 type Error = [Point2 <S>; 2];
198 fn try_from ([a, b] : [Point2 <S>; 2]) -> Result <Self, Self::Error> {
199 Self::new (a, b).ok_or([a, b])
200 }
201 }
202
203 impl <S : OrderedField> Triangle <S> {
204 pub fn new (a : Point2 <S>, b : Point2 <S>, c : Point2 <S>) -> Option <Self> where
215 S : approx::AbsDiffEq <Epsilon = S>
216 {
217 if colinear_2d (a, b, c) {
218 None
219 } else {
220 Some (Triangle { a, b, c })
221 }
222 }
223 pub fn noisy (a : Point2 <S>, b : Point2 <S>, c : Point2 <S>) -> Self where
233 S : approx::AbsDiffEq <Epsilon = S>
234 {
235 debug_assert_ne!(a, b);
236 debug_assert_ne!(a, c);
237 debug_assert_ne!(b, c);
238 assert!(!colinear_2d (a, b, c));
239 Triangle { a, b, c }
240 }
241 pub fn unchecked (a : Point2 <S>, b : Point2 <S>, c : Point2 <S>) -> Self where
251 S : approx::AbsDiffEq <Epsilon = S>
252 {
253 debug_assert_ne!(a, b);
254 debug_assert_ne!(a, c);
255 debug_assert_ne!(b, c);
256 debug_assert!(!colinear_2d (a, b, c));
257 Triangle { a, b, c }
258 }
259 #[inline]
260 pub fn from_array ([a, b, c] : [Point2 <S>; 3]) -> Option <Self> where
261 S : approx::AbsDiffEq <Epsilon = S>
262 {
263 Self::new (a, b, c)
264 }
265 #[inline]
266 pub const fn point_a (self) -> Point2 <S> {
267 self.a
268 }
269 #[inline]
270 pub const fn point_b (self) -> Point2 <S> {
271 self.b
272 }
273 #[inline]
274 pub const fn point_c (self) -> Point2 <S> {
275 self.c
276 }
277 #[inline]
278 pub const fn points (self) -> [Point2 <S>; 3] {
279 [self.a, self.b, self.c]
280 }
281 pub fn point (self, s : Normalized <S>, t : Normalized <S>) -> Option <Point2 <S>> {
285 if *s + *t > S::one() {
286 None
287 } else {
288 Some (self.a + (self.b - self.a) * *s + (self.c - self.a) * *t)
289 }
290 }
291 #[inline]
292 pub const fn edge_ab (self) -> Segment2 <S> {
293 Segment { a: self.a, b: self.b }
294 }
295 #[inline]
296 pub const fn edge_bc (self) -> Segment2 <S> {
297 Segment { a: self.b, b: self.c }
298 }
299 #[inline]
300 pub const fn edge_ca (self) -> Segment2 <S> {
301 Segment { a: self.c, b: self.a }
302 }
303 #[inline]
305 pub const fn edges (self) -> [Segment2 <S>; 3] {
306 [ self.edge_ab(), self.edge_bc(), self.edge_ca() ]
307 }
308 #[inline]
312 pub const fn rewind (self) -> Self {
313 self.acb()
314 }
315 #[inline]
317 pub const fn acb (self) -> Self {
318 Triangle { a: self.a, b: self.c, c: self.b }
319 }
320 #[inline]
321 pub fn translate (&mut self, displacement : Vector2 <S>) {
322 self.a += displacement;
323 self.b += displacement;
324 self.c += displacement;
325 }
326 pub fn perpendicular_ab (self) -> NonZero2 <S> {
342 let ac = self.c - self.a;
343 let mut perp = self.edge_ab().perpendicular();
344 if perp.dot (ac) > S::zero() {
345 perp = -perp
346 }
347 perp
348 }
349 pub fn perpendicular_bc (self) -> NonZero2 <S> {
365 let bc = self.c - self.b;
366 let ba = self.a - self.b;
367 let mut perp = bc.yx();
368 if perp.dot (ba) > S::zero() {
369 perp = -perp
370 }
371 NonZero2::unchecked (perp)
372 }
373 pub fn perpendicular_ca (self) -> NonZero2 <S> {
389 let ca = self.a - self.c;
390 let cb = self.b - self.c;
391 let mut perp = ca.yx();
392 if perp.dot (cb) > S::zero() {
393 perp = -perp
394 }
395 NonZero2::unchecked (perp)
396 }
397 #[inline]
398 pub fn area (self) -> Positive <S> where S : num::real::Real {
399 let ab = self.b - self.a;
400 let ac = self.c - self.a;
401 Positive::unchecked (ab.exterior_product (ac).abs())
402 }
403 pub fn barycentric (self, coords : Vector3 <S>) -> Point2 <S> {
404 (self.a.0 * coords.x + self.b.0 * coords.y + self.c.0 * coords.z).into()
405 }
406 pub fn trilinear (self, coords : Vector3 <S>) -> Point2 <S> where
407 S : Real + num::real::Real
408 {
409 let (ab, bc, ca) = (self.b - self.a, self.c - self.b, self.a - self.c);
410 let len_ab = ab.magnitude();
411 let len_bc = bc.magnitude();
412 let len_ca = ca.magnitude();
413 let ax = len_bc * coords.x;
414 let by = len_ca * coords.y;
415 let cz = len_ab * coords.z;
416 let denom = S::one() / (ax + by + cz);
417 (self.a.0 * ax * denom + self.b.0 * by * denom + self.c.0 * cz * denom).into()
418 }
419 #[inline]
420 pub fn affine_plane (self) -> frame::Plane2 <S> {
421 frame::Plane2 {
422 origin: self.a,
423 basis: frame::PlanarBasis2::new (Matrix2::from_col_arrays ([
424 (self.b - self.a).into_array(),
425 (self.c - self.a).into_array()
426 ])).unwrap()
427 }
428 }
429 #[inline]
430 pub fn nearest_point (self, point : Point2 <S>) -> TrianglePoint <S> {
431 distance::nearest_triangle2_point2 (self, point)
432 }
433 }
434 impl <S : Field + Sqrt> Default for Triangle <S> {
435 fn default() -> Self {
453 let frac_1_sqrt_2 = S::one() / (S::one() + S::one()).sqrt();
454 Triangle {
455 a: [ S::zero(), S::one()].into(),
456 b: [-frac_1_sqrt_2, -frac_1_sqrt_2].into(),
457 c: [ frac_1_sqrt_2, -frac_1_sqrt_2].into()
458 }
459 }
460 }
461 impl <S> std::ops::Index <usize> for Triangle <S> where S : Copy {
462 type Output = Point2 <S>;
463 fn index (&self, index : usize) -> &Point2 <S> {
464 [&self.a, &self.b, &self.c][index]
465 }
466 }
467 impl <S> TryFrom <[Point2 <S>; 3]> for Triangle <S>
468 where S : OrderedField + approx::AbsDiffEq <Epsilon = S>
469 {
470 type Error = [Point2 <S>; 3];
471 fn try_from ([a, b, c] : [Point2 <S>; 3]) -> Result <Self, Self::Error> {
472 Self::new (a, b, c).ok_or([a, b, c])
473 }
474 }
475}
476
477pub mod simplex3 {
479 #[cfg(feature = "derive_serdes")]
480 use serde::{Deserialize, Serialize};
481
482 use crate::*;
483 use crate::geometry::*;
484
485 pub type SegmentPoint <S> = (Normalized <S>, Point3 <S>);
487 pub type TrianglePoint <S> = ([Normalized <S>; 2], Point3 <S>);
489 pub type TetrahedronPoint <S> = ([Normalized <S>; 3], Point3 <S>);
491
492 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
497 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
498 pub enum Simplex3 <S> {
499 Segment (Segment <S>),
500 Triangle (Triangle <S>),
501 Tetrahedron (Tetrahedron <S>)
502 }
503
504 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
508 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
509 pub struct Segment <S> {
510 a : Point3 <S>,
511 b : Point3 <S>
512 }
513
514 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
518 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
519 pub struct Triangle <S> {
520 a : Point3 <S>,
521 b : Point3 <S>,
522 c : Point3 <S>
523 }
524
525 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
529 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
530 pub struct Tetrahedron <S> {
531 a : Point3 <S>,
532 b : Point3 <S>,
533 c : Point3 <S>,
534 d : Point3 <S>
535 }
536
537 impl <S : OrderedRing> Segment <S> {
538 pub fn new (a : Point3 <S>, b : Point3 <S>) -> Option <Self> {
545 if a == b {
546 None
547 } else {
548 Some (Segment { a, b })
549 }
550 }
551 pub fn noisy (a : Point3 <S>, b : Point3 <S>) -> Self {
558 assert_ne!(a, b);
559 Segment { a, b }
560 }
561 pub fn unchecked (a : Point3 <S>, b : Point3 <S>) -> Self {
568 debug_assert_ne!(a, b);
569 Segment { a, b }
570 }
571 #[inline]
572 pub fn from_array ([a, b] : [Point3 <S>; 2]) -> Option <Self> {
573 Self::new (a, b)
574 }
575 #[inline]
576 pub fn numcast <T> (self) -> Option <Segment <T>> where
577 S : num::NumCast,
578 T : num::NumCast
579 {
580 Some (Segment {
581 a: self.a.numcast()?,
582 b: self.b.numcast()?
583 })
584 }
585 #[inline]
586 pub const fn point_a (self) -> Point3 <S> {
587 self.a
588 }
589 #[inline]
590 pub const fn point_b (self) -> Point3 <S> {
591 self.b
592 }
593 #[inline]
594 pub const fn points (self) -> [Point3 <S>; 2] {
595 [self.a, self.b]
596 }
597 pub fn point (self, param : Normalized <S>) -> Point3 <S> {
599 self.a + *self.vector() * *param
600 }
601 #[inline]
602 pub fn length (self) -> NonNegative <S> where S : Field + Sqrt {
603 self.vector().norm()
604 }
605 #[inline]
606 pub fn length_squared (self) -> NonNegative <S> {
607 self.vector().self_dot()
608 }
609 #[inline]
611 pub fn vector (self) -> NonZero3 <S> {
612 NonZero3::unchecked (self.b - self.a)
613 }
614 #[inline]
616 pub fn perpendicular (self) -> NonZero3 <S> where
617 S : Field + approx::AbsDiffEq <Epsilon = S>
618 {
619 NonZero3::unchecked (self.vector().orthogonal())
620 }
621 #[inline]
622 pub fn translate (&mut self, displacement : Vector3 <S>) {
623 self.a += displacement;
624 self.b += displacement;
625 }
626 #[inline]
627 pub fn midpoint (self) -> Point3 <S> where S : Field {
628 ((self.a.0 + self.b.0) * S::half()).into()
629 }
630 #[inline]
631 pub fn aabb3 (self) -> Aabb3 <S> {
632 Aabb3::from_points_unchecked (self.a, self.b)
633 }
634 #[inline]
635 pub fn line (self) -> Line3 <S> where S : Field + Sqrt {
636 Line3::new (self.a, Unit3::normalize (*self.vector()))
637 }
638 pub fn affine_line (self) -> frame::Line3 <S> {
639 frame::Line3 {
640 origin: self.a,
641 basis: self.vector()
642 }
643 }
644 #[inline]
645 pub fn nearest_point (self, point : Point3 <S>) -> SegmentPoint <S> where
646 S : Field
647 {
648 distance::nearest_segment3_point3 (self, point)
649 }
650 #[inline]
651 pub fn intersect_aabb (self, aabb : Aabb3 <S>)
652 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
653 where S : Real + num::Float + approx::RelativeEq <Epsilon=S> {
654 intersect::continuous_segment3_aabb3 (self, aabb)
655 }
656 #[inline]
657 pub fn intersect_triangle (self, triangle : Triangle3 <S>)
658 -> Option <SegmentPoint <S>>
659 where S : Real + num::real::Real + approx::AbsDiffEq <Epsilon=S> {
660 intersect::continuous_triangle3_segment3 (triangle, self)
661 }
662 #[inline]
663 pub fn intersect_sphere (self, sphere : Sphere3 <S>)
664 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
665 where S : Field + Sqrt {
666 intersect::continuous_segment3_sphere3 (self, sphere)
667 }
668 #[inline]
669 pub fn intersect_cylinder (self, sphere : Cylinder3 <S>)
670 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
671 where S : Real {
672 intersect::continuous_segment3_cylinder3 (self, sphere)
673 }
674 #[inline]
675 pub fn intersect_capsule (self, capsule : Capsule3 <S>)
676 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
677 where S : Real {
678 intersect::continuous_segment3_capsule3 (self, capsule)
679 }
680 #[inline]
681 pub fn intersect_hull (self, hull : &Hull3 <S>)
682 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
683 {
684 intersect::continuous_segment3_hull3 (self, hull)
685 }
686 }
687 impl <S : Ring> Default for Segment <S> {
688 fn default() -> Self {
699 Segment {
700 a: [-S::one(), S::zero(), S::zero()].into(),
701 b: [ S::one(), S::zero(), S::zero()].into()
702 }
703 }
704 }
705 impl <S> std::ops::Index <usize> for Segment <S> where S : Copy {
706 type Output = Point3 <S>;
707 fn index (&self, index : usize) -> &Point3 <S> {
708 [&self.a, &self.b][index]
709 }
710 }
711 impl <S> TryFrom <[Point3 <S>; 2]> for Segment <S> where S : OrderedRing {
712 type Error = [Point3 <S>; 2];
713 fn try_from ([a, b] : [Point3 <S>; 2]) -> Result <Self, Self::Error> {
714 Self::new (a, b).ok_or([a, b])
715 }
716 }
717
718 impl <S : OrderedField> Triangle <S> {
719 pub fn new (a : Point3 <S>, b : Point3 <S>, c : Point3 <S>) -> Option <Self> where
730 S : Sqrt + approx::RelativeEq <Epsilon = S>
731 {
732 if colinear_3d (a, b, c) {
733 None
734 } else {
735 Some (Triangle { a, b, c })
736 }
737 }
738 pub fn noisy (a : Point3 <S>, b : Point3 <S>, c : Point3 <S>) -> Self where
748 S : Sqrt + approx::RelativeEq <Epsilon = S>
749 {
750 debug_assert_ne!(a, b);
751 debug_assert_ne!(a, c);
752 debug_assert_ne!(b, c);
753 assert!(!colinear_3d (a, b, c));
754 Triangle { a, b, c }
755 }
756 pub fn unchecked (a : Point3 <S>, b : Point3 <S>, c : Point3 <S>) -> Self where
766 S : Sqrt + approx::RelativeEq <Epsilon = S>
767 {
768 debug_assert_ne!(a, b);
769 debug_assert_ne!(a, c);
770 debug_assert_ne!(b, c);
771 debug_assert!(!colinear_3d (a, b, c));
772 Triangle { a, b, c }
773 }
774 #[inline]
775 pub fn from_array ([a, b, c] : [Point3 <S>; 3]) -> Option <Self> where
776 S : Sqrt + approx::RelativeEq <Epsilon = S>
777 {
778 Self::new (a, b, c)
779 }
780 #[inline]
781 pub const fn point_a (self) -> Point3 <S> {
782 self.a
783 }
784 #[inline]
785 pub const fn point_b (self) -> Point3 <S> {
786 self.b
787 }
788 #[inline]
789 pub const fn point_c (self) -> Point3 <S> {
790 self.c
791 }
792 #[inline]
793 pub const fn points (self) -> [Point3 <S>; 3] {
794 [self.a, self.b, self.c]
795 }
796 pub fn point (self, s : Normalized <S>, t : Normalized <S>) -> Option <Point3 <S>> {
800 if *s + *t > S::one() {
801 None
802 } else {
803 Some (self.a + (self.b - self.a) * *s + (self.c - self.a) * *t)
804 }
805 }
806 #[inline]
807 pub const fn edge_ab (self) -> Segment3 <S> {
808 Segment { a: self.a, b: self.b }
809 }
810 #[inline]
811 pub const fn edge_bc (self) -> Segment3 <S> {
812 Segment { a: self.b, b: self.c }
813 }
814 #[inline]
815 pub const fn edge_ca (self) -> Segment3 <S> {
816 Segment { a: self.c, b: self.a }
817 }
818 #[inline]
819 pub const fn edges (self) -> [Segment3 <S>; 3] {
820 [ Segment { a: self.a, b: self.b },
821 Segment { a: self.b, b: self.c },
822 Segment { a: self.c, b: self.a }
823 ]
824 }
825 #[inline]
829 pub const fn rewind (self) -> Self {
830 self.acb()
831 }
832 #[inline]
834 pub const fn acb (self) -> Self {
835 Triangle { a: self.a, b: self.c, c: self.b }
836 }
837 pub fn translate (&mut self, displacement : Vector3 <S>) where
838 S : Copy + AdditiveGroup
839 {
840 self.a += displacement;
841 self.b += displacement;
842 self.c += displacement;
843 }
844 #[inline]
846 pub fn normal (self) -> NonZero3 <S> {
847 let ab = self.b - self.a;
848 let ac = self.c - self.b;
849 NonZero3::unchecked (ab.cross (ac))
850 }
851 #[inline]
853 pub fn unit_normal (self) -> Unit3 <S> where S : Sqrt {
854 self.normal().normalize()
855 }
856 pub fn perpendicular_ab (self) -> NonZero3 <S> {
873 let ab = self.b - self.a;
874 let ac = self.c - self.a;
875 let perp = ab.cross (ab.cross (ac));
876 debug_assert!(perp.dot (ac) < S::zero());
877 NonZero3::unchecked (perp)
878 }
879 pub fn perpendicular_bc (self) -> NonZero3 <S> {
896 let bc = self.c - self.b;
897 let ba = self.a - self.b;
898 let perp = bc.cross (bc.cross (ba));
899 debug_assert!(perp.dot (ba) < S::zero());
900 NonZero3::unchecked (perp)
901 }
902 pub fn perpendicular_ca (self) -> NonZero3 <S> {
919 let ca = self.a - self.c;
920 let cb = self.b - self.c;
921 let perp = ca.cross (ca.cross (cb));
922 debug_assert!(perp.dot (cb) < S::zero());
923 NonZero3::unchecked (perp)
924 }
925 #[inline]
926 pub fn area (self) -> Positive <S> where S : Sqrt {
927 Positive::unchecked (*self.normal().norm() * S::half())
928 }
929 pub fn barycentric (self, coords : Vector3 <S>) -> Point3 <S> {
930 (self.a.0 * coords.x + self.b.0 * coords.y + self.c.0 * coords.z).into()
931 }
932 pub fn trilinear (self, coords : Vector3 <S>) -> Point3 <S> where
933 S : Real + num::real::Real
934 {
935 let (ab, bc, ca) = (self.b - self.a, self.c - self.b, self.a - self.c);
936 let len_ab = ab.magnitude();
937 let len_bc = bc.magnitude();
938 let len_ca = ca.magnitude();
939 let ax = len_bc * coords.x;
940 let by = len_ca * coords.y;
941 let cz = len_ab * coords.z;
942 let denom = S::one() / (ax + by + cz);
943 (self.a.0 * ax * denom + self.b.0 * by * denom + self.c.0 * cz * denom).into()
944 }
945 #[inline]
946 pub fn affine_plane (self) -> frame::Plane3 <S> {
947 frame::Plane3 {
948 origin: self.a,
949 basis: frame::PlanarBasis3::new ([
950 (self.b - self.a),
951 (self.c - self.a)
952 ].map (NonZero3::unchecked)).unwrap()
953 }
954 }
955 #[inline]
956 pub fn nearest_point (self, point : Point3 <S>) -> TrianglePoint <S> {
957 distance::nearest_triangle3_point3 (self, point)
958 }
959 }
960 impl <S : Field + Sqrt> Default for Triangle <S> {
961 fn default() -> Self {
988 let frac_1_sqrt_2 = S::one() / (S::one() + S::one()).sqrt();
989 Triangle {
990 a: [ S::zero(), S::one(), S::zero()].into(),
991 b: [-frac_1_sqrt_2, -frac_1_sqrt_2, S::zero()].into(),
992 c: [ frac_1_sqrt_2, -frac_1_sqrt_2, S::zero()].into()
993 }
994 }
995 }
996 impl <S> std::ops::Index <usize> for Triangle <S> where S : Copy {
997 type Output = Point3 <S>;
998 fn index (&self, index : usize) -> &Point3 <S> {
999 [&self.a, &self.b, &self.c][index]
1000 }
1001 }
1002 impl <S> TryFrom <[Point3 <S>; 3]> for Triangle <S> where
1003 S : OrderedField + Sqrt + approx::RelativeEq <Epsilon = S>
1004 {
1005 type Error = [Point3 <S>; 3];
1006 fn try_from ([a, b, c] : [Point3 <S>; 3]) -> Result <Self, Self::Error> {
1007 Self::new (a, b, c).ok_or([a, b, c])
1008 }
1009 }
1010
1011 impl <S : OrderedField> Tetrahedron <S> {
1012 pub fn new (a : Point3 <S>, b : Point3 <S>, c : Point3 <S>, d : Point3 <S>)
1024 -> Option <Self>
1025 where S : approx::AbsDiffEq <Epsilon = S> {
1026 if coplanar_3d (a, b, c, d) {
1027 None
1028 } else {
1029 Some (Tetrahedron { a, b, c, d })
1030 }
1031 }
1032 pub fn noisy (a : Point3 <S>, b : Point3 <S>, c : Point3 <S>, d : Point3 <S>)
1043 -> Self
1044 where S : approx::AbsDiffEq <Epsilon = S> {
1045 assert!(!coplanar_3d (a, b, c, d));
1046 Tetrahedron { a, b, c, d }
1047 }
1048 pub fn unchecked (a : Point3 <S>, b : Point3 <S>, c : Point3 <S>, d : Point3 <S>)
1059 -> Self
1060 where S : approx::AbsDiffEq <Epsilon = S> {
1061 debug_assert!(!coplanar_3d (a, b, c, d));
1062 Tetrahedron { a, b, c, d }
1063 }
1064 #[inline]
1065 pub fn from_array ([a, b, c, d] : [Point3 <S>; 4]) -> Option <Self> where
1066 S : approx::AbsDiffEq <Epsilon = S>
1067 {
1068 Self::new (a, b, c, d)
1069 }
1070 #[inline]
1071 pub const fn point_a (self) -> Point3 <S> {
1072 self.a
1073 }
1074 #[inline]
1075 pub const fn point_b (self) -> Point3 <S> {
1076 self.b
1077 }
1078 #[inline]
1079 pub const fn point_c (self) -> Point3 <S> {
1080 self.c
1081 }
1082 #[inline]
1083 pub const fn point_d (self) -> Point3 <S> {
1084 self.d
1085 }
1086 #[inline]
1087 pub const fn points (self) -> [Point3 <S>; 4] {
1088 [self.a, self.b, self.c, self.d]
1089 }
1090 #[inline]
1091 pub const fn edge_ab (self) -> Segment3 <S> {
1092 Segment { a: self.a, b: self.b }
1093 }
1094 #[inline]
1095 pub const fn edge_ac (self) -> Segment3 <S> {
1096 Segment { a: self.a, b: self.c }
1097 }
1098 #[inline]
1099 pub const fn edge_ad (self) -> Segment3 <S> {
1100 Segment { a: self.a, b: self.d }
1101 }
1102 #[inline]
1103 pub const fn edge_bc (self) -> Segment3 <S> {
1104 Segment { a: self.b, b: self.c }
1105 }
1106 #[inline]
1107 pub const fn edge_bd (self) -> Segment3 <S> {
1108 Segment { a: self.b, b: self.d }
1109 }
1110 #[inline]
1111 pub const fn edge_cd (self) -> Segment3 <S> {
1112 Segment { a: self.c, b: self.d }
1113 }
1114 #[inline]
1115 pub const fn edges (self) -> [Segment3 <S>; 6] {
1116 [ self.edge_ab(),
1117 self.edge_ac(),
1118 self.edge_ad(),
1119 self.edge_bc(),
1120 self.edge_bd(),
1121 self.edge_cd()
1122 ]
1123 }
1124 #[inline]
1127 pub fn face_abc (self) -> Triangle <S> {
1128 let triangle = Triangle { a: self.a, b: self.b, c: self.c };
1129 if triangle.normal().dot (self.d - self.a) > S::zero() {
1130 triangle.rewind()
1131 } else {
1132 triangle
1133 }
1134 }
1135 #[inline]
1138 pub fn face_abd (self) -> Triangle <S> {
1139 let triangle = Triangle { a: self.a, b: self.b, c: self.d };
1140 if triangle.normal().dot (self.c - self.a) > S::zero() {
1141 triangle.rewind()
1142 } else {
1143 triangle
1144 }
1145 }
1146 #[inline]
1149 pub fn face_acd (self) -> Triangle <S> {
1150 let triangle = Triangle { a: self.a, b: self.c, c: self.d };
1151 if triangle.normal().dot (self.b - self.a) > S::zero() {
1152 triangle.rewind()
1153 } else {
1154 triangle
1155 }
1156 }
1157 #[inline]
1160 pub fn face_bcd (self) -> Triangle <S> {
1161 let triangle = Triangle { a: self.b, b: self.c, c: self.d };
1162 if triangle.normal().dot (self.a - self.b) > S::zero() {
1163 triangle.rewind()
1164 } else {
1165 triangle
1166 }
1167 }
1168 #[inline]
1169 pub fn faces (self) -> [Triangle <S>; 4] {
1170 [ self.face_abc(),
1171 self.face_abd(),
1172 self.face_acd(),
1173 self.face_bcd()
1174 ]
1175 }
1176 pub fn normal_abc (self) -> NonZero3 <S> {
1177 let mut abc_normal = self.face_abc().normal();
1178 let ad = self.d - self.a;
1179 if abc_normal.dot (ad) > S::zero() {
1180 abc_normal = -abc_normal;
1181 }
1182 abc_normal
1183 }
1184 pub fn normal_abd (self) -> NonZero3 <S> {
1185 let mut abd_normal = self.face_abd().normal();
1186 let ac = self.c - self.a;
1187 if abd_normal.dot (ac) > S::zero() {
1188 abd_normal = -abd_normal;
1189 }
1190 abd_normal
1191 }
1192 pub fn normal_acd (self) -> NonZero3 <S> {
1193 let mut acd_normal = self.face_acd().normal();
1194 let ab = self.b - self.a;
1195 if acd_normal.dot (ab) > S::zero() {
1196 acd_normal = -acd_normal;
1197 }
1198 acd_normal
1199 }
1200 pub fn normal_bcd (self) -> NonZero3 <S> {
1201 let mut bcd_normal = self.face_bcd().normal();
1202 let ba = self.a - self.b;
1203 if bcd_normal.dot (ba) > S::zero() {
1204 bcd_normal = -bcd_normal;
1205 }
1206 bcd_normal
1207 }
1208 pub fn volume (self) -> Positive <S> {
1209 Positive::unchecked (
1210 (self.b - self.a).cross (self.c - self.a).dot (self.d - self.a).abs()
1211 * (S::one() / S::six()))
1212 }
1213 #[inline]
1214 pub fn translate (&mut self, displacement : Vector3 <S>) {
1215 self.a += displacement;
1216 self.b += displacement;
1217 self.c += displacement;
1218 self.d += displacement;
1219 }
1220 #[inline]
1235 pub fn contains (self, point : Point3 <S>) -> bool {
1236 let ap = point - self.a;
1237 let bp = point - self.b;
1238 self.normal_abc().dot (ap) < S::zero() &&
1239 self.normal_abd().dot (ap) < S::zero() &&
1240 self.normal_acd().dot (ap) < S::zero() &&
1241 self.normal_bcd().dot (bp) < S::zero()
1242 }
1243 }
1244 impl <S : Field + Sqrt> Default for Tetrahedron <S> {
1245 fn default() -> Self {
1276 let frac_1_3 = S::one() / S::three();
1277 let sqrt_2_3 = (S::two() / S::three()).sqrt();
1278 let sqrt_8_9 = (S::eight() / S::nine()).sqrt();
1279 let sqrt_2_9 = (S::two() / S::nine()).sqrt();
1280 Tetrahedron {
1281 a: [S::zero(), S::zero(), S::one()].into(),
1282 b: [S::zero(), sqrt_8_9, -frac_1_3].into(),
1283 c: [ sqrt_2_3, -sqrt_2_9, -frac_1_3].into(),
1284 d: [-sqrt_2_3, -sqrt_2_9, -frac_1_3].into()
1285 }
1286 }
1287 }
1288 impl <S> std::ops::Index <usize> for Tetrahedron <S> where S : Copy {
1289 type Output = Point3 <S>;
1290 fn index (&self, index : usize) -> &Point3 <S> {
1291 [&self.a, &self.b, &self.c, &self.d][index]
1292 }
1293 }
1294
1295 impl <S> TryFrom <[Point3 <S>; 4]> for Tetrahedron <S> where
1296 S : OrderedField + approx::RelativeEq <Epsilon = S>
1297 {
1298 type Error = [Point3 <S>; 4];
1299 fn try_from ([a, b, c, d] : [Point3 <S>; 4]) -> Result <Self, Self::Error> {
1300 Self::new (a, b, c, d).ok_or([a, b, c, d])
1301 }
1302 }
1303}
1304
1305#[cfg(test)]
1306mod tests {
1307 use crate::approx;
1308 use crate::geometry::*;
1309 use super::*;
1310
1311 #[test]
1312 fn barycentric_2() {
1313 let triangle = simplex2::Triangle::noisy (
1314 [-2.0, -2.0].into(), [2.0, -2.0].into(), [0.0, 2.0].into());
1315 assert_eq!(triangle.barycentric ([1.0, 0.0, 0.0].into()), [-2.0, -2.0].into());
1316 assert_eq!(triangle.barycentric ([0.0, 1.0, 0.0].into()), [ 2.0, -2.0].into());
1317 assert_eq!(triangle.barycentric ([0.0, 0.0, 1.0].into()), [ 0.0, 2.0].into());
1318 assert_eq!(triangle.barycentric ([0.5, 0.5, 0.0].into()), [ 0.0, -2.0].into());
1319 assert_eq!(triangle.barycentric ([0.5, 0.0, 0.5].into()), [-1.0, 0.0].into());
1320 assert_eq!(triangle.barycentric ([0.0, 0.5, 0.5].into()), [ 1.0, 0.0].into());
1321 }
1322
1323 #[test]
1324 fn barycentric_3() {
1325 let triangle = simplex3::Triangle::noisy (
1326 [-2.0, -2.0, 0.0].into(), [2.0, -2.0, 0.0].into(), [0.0, 2.0, 0.0].into());
1327 assert_eq!(triangle.barycentric ([1.0, 0.0, 0.0].into()), [-2.0, -2.0, 0.0].into());
1328 assert_eq!(triangle.barycentric ([0.0, 1.0, 0.0].into()), [ 2.0, -2.0, 0.0].into());
1329 assert_eq!(triangle.barycentric ([0.0, 0.0, 1.0].into()), [ 0.0, 2.0, 0.0].into());
1330 assert_eq!(triangle.barycentric ([0.5, 0.5, 0.0].into()), [ 0.0, -2.0, 0.0].into());
1331 assert_eq!(triangle.barycentric ([0.5, 0.0, 0.5].into()), [-1.0, 0.0, 0.0].into());
1332 assert_eq!(triangle.barycentric ([0.0, 0.5, 0.5].into()), [ 1.0, 0.0, 0.0].into());
1333 }
1334
1335 #[test]
1336 fn trilinear_2() {
1337 let triangle = simplex2::Triangle::noisy (
1338 [-2.0, -2.0].into(), [2.0, -2.0].into(), [0.0, 2.0].into());
1339 assert_eq!(triangle.trilinear ([1.0, 0.0, 0.0].into()), [-2.0, -2.0].into());
1340 assert_eq!(triangle.trilinear ([0.0, 1.0, 0.0].into()), [ 2.0, -2.0].into());
1341 assert_eq!(triangle.trilinear ([0.0, 0.0, 1.0].into()), [ 0.0, 2.0].into());
1342 assert_eq!(triangle.trilinear (
1344 [1.0 / 20.0f32.sqrt(), 1.0 / 20.0f32.sqrt(), 0.25].into()),
1345 [0.0, -2.0/3.0].into());
1346 approx::assert_relative_eq!(triangle.trilinear (
1348 [1.0, 1.0, 1.0].into()),
1349 [ 0.0, 5.0f32.sqrt() - 3.0].into());
1350 }
1351
1352 #[test]
1353 fn trilinear_3() {
1354 let triangle = simplex3::Triangle::noisy (
1355 [-2.0, -2.0, 0.0].into(), [2.0, -2.0, 0.0].into(), [0.0, 2.0, 0.0].into());
1356 assert_eq!(triangle.trilinear ([1.0, 0.0, 0.0].into()), [-2.0, -2.0, 0.0].into());
1357 assert_eq!(triangle.trilinear ([0.0, 1.0, 0.0].into()), [ 2.0, -2.0, 0.0].into());
1358 assert_eq!(triangle.trilinear ([0.0, 0.0, 1.0].into()), [ 0.0, 2.0, 0.0].into());
1359 assert_eq!(triangle.trilinear (
1361 [1.0 / 20.0f32.sqrt(), 1.0 / 20.0f32.sqrt(), 0.25].into()),
1362 [0.0, -2.0/3.0, 0.0].into());
1363 approx::assert_relative_eq!(triangle.trilinear (
1365 [1.0, 1.0, 1.0].into()),
1366 [ 0.0, 5.0f32.sqrt() - 3.0, 0.0].into());
1367 }
1368
1369 #[test]
1370 fn tetrahedron_face_normals() {
1371 use rand;
1373 use rand_xorshift::XorShiftRng;
1374 use rand::SeedableRng;
1375 let aabb = Aabb3::<f32>::with_minmax_unchecked (
1376 [-10.0, -10.0, -10.0].into(),
1377 [ 10.0, 10.0, 10.0].into());
1378 let mut rng = XorShiftRng::seed_from_u64 (0);
1379 for _ in 0..10000 {
1380 let t = Tetrahedron3::noisy (
1381 aabb.rand_point (&mut rng),
1382 aabb.rand_point (&mut rng),
1383 aabb.rand_point (&mut rng),
1384 aabb.rand_point (&mut rng));
1385 for face in t.faces() {
1386 let other_p = {
1387 let mut point = None;
1388 for p in t.points() {
1389 if !face.points().contains (&p) {
1390 point = Some (p);
1391 break
1392 }
1393 }
1394 point.unwrap()
1395 };
1396 assert!(face.normal().dot (other_p - face.point_a()) < 0.0);
1397 }
1398 }
1399 }
1400}