1pub use self::simplex2::Simplex2;
2pub use self::simplex3::Simplex3;
3
4#[macro_use]
5mod macro_def;
6
7pub mod simplex2 {
9 #[cfg(feature = "derive_serdes")]
10 use serde::{Deserialize, Serialize};
11
12 use crate::*;
13 use crate::geometry::*;
14
15 pub type SegmentPoint <S> = (Normalized <S>, Point2 <S>);
17 pub type TrianglePoint <S> = ([Normalized <S>; 2], Point2 <S>);
19
20 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
25 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
26 pub enum Simplex2 <S> {
27 Segment (Segment <S>),
28 Triangle (Triangle <S>)
29 }
30
31 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
35 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
36 pub struct Segment <S> {
37 a : Point2 <S>,
38 b : Point2 <S>
39 }
40
41 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
45 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
46 pub struct Triangle <S> {
47 a : Point2 <S>,
48 b : Point2 <S>,
49 c : Point2 <S>
50 }
51
52 impl_accessors!(Segment, Point2, 2, [(point_a, a), (point_b, b)]);
53 impl_accessors!(Triangle, Point2, 3, [(point_a, a), (point_b, b), (point_c, c)]);
54
55 impl <S : OrderedRing> Segment <S> {
56 pub fn new (a : Point2 <S>, b : Point2 <S>) -> Option <Self> {
63 if a == b {
64 None
65 } else {
66 Some (Segment { a, b })
67 }
68 }
69 pub fn noisy (a : Point2 <S>, b : Point2 <S>) -> Self {
76 assert_ne!(a, b);
77 Segment { a, b }
78 }
79 pub fn unchecked (a : Point2 <S>, b : Point2 <S>) -> Self {
86 debug_assert_ne!(a, b);
87 Segment { a, b }
88 }
89 #[inline]
90 pub fn from_array ([a, b] : [Point2 <S>; 2]) -> Option <Self> {
91 Self::new (a, b)
92 }
93 #[inline]
94 pub fn numcast <T> (self) -> Option <Segment <T>> where
95 S : num::NumCast,
96 T : num::NumCast
97 {
98 Some (Segment {
99 a: self.a.numcast()?,
100 b: self.b.numcast()?
101 })
102 }
103 pub fn point (self, param : Normalized <S>) -> Point2 <S> {
105 self.a + *self.vector() * param
106 }
107 #[inline]
108 pub fn length (self) -> NonNegative <S> where S : Field + Sqrt {
109 self.vector().norm()
110 }
111 #[inline]
112 pub fn length_squared (self) -> NonNegative <S> {
113 self.vector().self_dot()
114 }
115 #[inline]
117 pub fn vector (self) -> NonZero2 <S> {
118 NonZero2::unchecked (self.b - self.a)
119 }
120 #[inline]
121 pub fn perpendicular (self) -> NonZero2 <S> {
122 self.vector().map_unchecked (Vector2::yx)
123 }
124 #[inline]
125 pub fn midpoint (self) -> Point2 <S> where S : Field {
126 ((self.a.0 + self.b.0) * S::half()).into()
127 }
128 #[inline]
129 pub fn aabb2 (self) -> Aabb2 <S> {
130 Aabb2::from_points_unchecked (self.a, self.b)
131 }
132 #[inline]
133 pub fn line (self) -> Line2 <S> where S : Real {
134 Line2::new (self.a, self.vector().normalize())
135 }
136 pub fn affine_line (self) -> frame::Line2 <S> {
137 frame::Line2 {
138 origin: self.a,
139 basis: self.vector()
140 }
141 }
142 #[inline]
143 pub fn nearest_point (self, point : Point2 <S>) -> SegmentPoint <S> where
144 S : Field
145 {
146 distance::nearest_segment2_point2 (self, point)
147 }
148 #[inline]
149 pub fn intersect_aabb (self, aabb : Aabb2 <S>)
150 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
151 where S : Real {
152 intersect::intersect_segment2_aabb2 (self, aabb)
153 }
154 #[inline]
155 pub fn intersect_sphere (self, sphere : Sphere2 <S>)
156 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
157 where S : Real {
158 intersect::intersect_segment2_sphere2 (self, sphere)
159 }
160 }
161 impl <S : Ring> Default for Segment <S> {
162 fn default() -> Self {
173 Segment {
174 a: [-S::one(), S::zero()].into(),
175 b: [ S::one(), S::zero()].into()
176 }
177 }
178 }
179 impl <S> std::ops::Index <usize> for Segment <S> where S : Copy {
180 type Output = Point2 <S>;
181 fn index (&self, index : usize) -> &Point2 <S> {
182 [&self.a, &self.b][index]
183 }
184 }
185 impl <S> TryFrom <[Point2 <S>; 2]> for Segment <S> where S : OrderedRing {
186 type Error = [Point2 <S>; 2];
187 fn try_from ([a, b] : [Point2 <S>; 2]) -> Result <Self, Self::Error> {
188 Self::new (a, b).ok_or([a, b])
189 }
190 }
191 impl <S> Primitive <S, Point2 <S>> for Segment <S> where
192 S : OrderedField + approx::AbsDiffEq
193 {
194 fn translate (&mut self, displacement : Vector2 <S>) {
195 self.a += displacement;
196 self.b += displacement;
197 }
198 fn scale (&mut self, scale : Positive <S>) {
199 let midpoint = self.midpoint();
200 self.translate (-midpoint.0);
201 self.a = Point2 (self.a.0 * scale);
202 self.b = Point2 (self.b.0 * scale);
203 self.translate (midpoint.0);
204 }
205 fn support (&self, direction : NonZero2 <S>) -> (Point2 <S>, S) {
206 let [dot_a, dot_b] = self.points().map (|p| direction.dot (p.0));
207 if dot_a >= dot_b {
208 (self.a, dot_a)
209 } else {
210 (self.b, dot_b)
211 }
212 }
213 }
214
215 impl <S : OrderedField> Triangle <S> {
216 pub fn new (a : Point2 <S>, b : Point2 <S>, c : Point2 <S>) -> Option <Self> where
227 S : approx::AbsDiffEq <Epsilon = S>
228 {
229 if colinear_2 (a, b, c) {
230 None
231 } else {
232 Some (Triangle { a, b, c })
233 }
234 }
235 pub fn noisy (a : Point2 <S>, b : Point2 <S>, c : Point2 <S>) -> Self where
245 S : approx::AbsDiffEq <Epsilon = S>
246 {
247 debug_assert_ne!(a, b);
248 debug_assert_ne!(a, c);
249 debug_assert_ne!(b, c);
250 assert!(!colinear_2 (a, b, c));
251 Triangle { a, b, c }
252 }
253 pub fn unchecked (a : Point2 <S>, b : Point2 <S>, c : Point2 <S>) -> Self where
263 S : approx::AbsDiffEq <Epsilon = S>
264 {
265 debug_assert_ne!(a, b);
266 debug_assert_ne!(a, c);
267 debug_assert_ne!(b, c);
268 debug_assert!(!colinear_2 (a, b, c));
269 Triangle { a, b, c }
270 }
271 #[inline]
272 pub fn from_array ([a, b, c] : [Point2 <S>; 3]) -> Option <Self> where
273 S : approx::AbsDiffEq <Epsilon = S>
274 {
275 Self::new (a, b, c)
276 }
277 pub fn point (self, s : Normalized <S>, t : Normalized <S>) -> Option <Point2 <S>> {
281 if *s + *t > S::one() {
282 None
283 } else {
284 Some (self.a + (self.b - self.a) * s + (self.c - self.a) * t)
285 }
286 }
287 #[inline]
288 pub const fn edge_ab (self) -> Segment2 <S> {
289 Segment { a: self.a, b: self.b }
290 }
291 #[inline]
292 pub const fn edge_bc (self) -> Segment2 <S> {
293 Segment { a: self.b, b: self.c }
294 }
295 #[inline]
296 pub const fn edge_ca (self) -> Segment2 <S> {
297 Segment { a: self.c, b: self.a }
298 }
299 #[inline]
301 pub const fn edges (self) -> [Segment2 <S>; 3] {
302 [ self.edge_ab(), self.edge_bc(), self.edge_ca() ]
303 }
304 #[inline]
308 pub const fn rewind (self) -> Self {
309 self.acb()
310 }
311 #[inline]
313 pub const fn acb (self) -> Self {
314 Triangle { a: self.a, b: self.c, c: self.b }
315 }
316 pub fn perpendicular_ab (self) -> NonZero2 <S> {
332 let ac = self.c - self.a;
333 let mut perp = self.edge_ab().perpendicular();
334 if perp.dot (ac) > S::zero() {
335 perp = -perp
336 }
337 perp
338 }
339 pub fn perpendicular_bc (self) -> NonZero2 <S> {
355 let bc = self.c - self.b;
356 let ba = self.a - self.b;
357 let mut perp = bc.yx();
358 if perp.dot (ba) > S::zero() {
359 perp = -perp
360 }
361 NonZero2::unchecked (perp)
362 }
363 pub fn perpendicular_ca (self) -> NonZero2 <S> {
379 let ca = self.a - self.c;
380 let cb = self.b - self.c;
381 let mut perp = ca.yx();
382 if perp.dot (cb) > S::zero() {
383 perp = -perp
384 }
385 NonZero2::unchecked (perp)
386 }
387 #[inline]
388 pub fn area (self) -> Positive <S> where S : num::real::Real {
389 let ab = self.b - self.a;
390 let ac = self.c - self.a;
391 Positive::unchecked (ab.exterior_product (ac).abs())
392 }
393 #[inline]
396 pub fn centroid (self) -> Point2 <S> {
397 self.barycentric (Vector3::broadcast (S::one() / S::three()))
398 }
399 #[inline]
402 pub fn incenter (self) -> Point2 <S> where S : Real + num::real::Real {
403 self.trilinear (Vector3::one())
404 }
405 pub fn barycentric (self, coords : Vector3 <S>) -> Point2 <S> {
406 (self.a.0 * coords.x + self.b.0 * coords.y + self.c.0 * coords.z).into()
407 }
408 pub fn trilinear (self, coords : Vector3 <S>) -> Point2 <S> where
409 S : Real + num::real::Real
410 {
411 let (ab, bc, ca) = (self.b - self.a, self.c - self.b, self.a - self.c);
412 let len_ab = ab.magnitude();
413 let len_bc = bc.magnitude();
414 let len_ca = ca.magnitude();
415 let ax = len_bc * coords.x;
416 let by = len_ca * coords.y;
417 let cz = len_ab * coords.z;
418 let denom = S::one() / (ax + by + cz);
419 (self.a.0 * ax * denom + self.b.0 * by * denom + self.c.0 * cz * denom).into()
420 }
421 #[inline]
422 pub fn affine_plane (self) -> frame::Plane2 <S> {
423 frame::Plane2 {
424 origin: self.a,
425 basis: frame::PlanarBasis2::new (Matrix2::from_col_arrays ([
426 (self.b - self.a).into_array(),
427 (self.c - self.a).into_array()
428 ])).unwrap()
429 }
430 }
431 #[inline]
432 pub fn nearest_point (self, point : Point2 <S>) -> TrianglePoint <S> {
433 distance::nearest_triangle2_point2 (self, point)
434 }
435 }
436 impl <S : Field + Sqrt> Default for Triangle <S> {
437 fn default() -> Self {
455 let frac_1_sqrt_2 = S::one() / (S::one() + S::one()).sqrt();
456 Triangle {
457 a: [ S::zero(), S::one()].into(),
458 b: [-frac_1_sqrt_2, -frac_1_sqrt_2].into(),
459 c: [ frac_1_sqrt_2, -frac_1_sqrt_2].into()
460 }
461 }
462 }
463 impl <S> std::ops::Index <usize> for Triangle <S> where S : Copy {
464 type Output = Point2 <S>;
465 fn index (&self, index : usize) -> &Point2 <S> {
466 [&self.a, &self.b, &self.c][index]
467 }
468 }
469 impl <S> TryFrom <[Point2 <S>; 3]> for Triangle <S>
470 where S : OrderedField + approx::AbsDiffEq <Epsilon = S>
471 {
472 type Error = [Point2 <S>; 3];
473 fn try_from ([a, b, c] : [Point2 <S>; 3]) -> Result <Self, Self::Error> {
474 Self::new (a, b, c).ok_or([a, b, c])
475 }
476 }
477 impl <S> Primitive <S, Point2 <S>> for Triangle <S> where
478 S : OrderedField + approx::AbsDiffEq
479 {
480 fn translate (&mut self, displacement : Vector2 <S>) {
481 self.a += displacement;
482 self.b += displacement;
483 self.c += displacement;
484 }
485 fn scale (&mut self, scale : Positive <S>) {
486 let centroid = self.centroid();
487 self.translate (-centroid.0);
488 self.a = Point2 (self.a.0 * scale);
489 self.b = Point2 (self.b.0 * scale);
490 self.c = Point2 (self.c.0 * scale);
491 self.translate (centroid.0);
492 }
493 fn support (&self, direction : NonZero2 <S>) -> (Point2 <S>, S) {
494 let [dot_a, dot_b, dot_c] = self.points().map (|p| direction.dot (p.0));
495 if dot_a >= dot_b && dot_a >= dot_c {
496 (self.a, dot_a)
497 } else if dot_b >= dot_c {
498 (self.b, dot_b)
499 } else {
500 (self.c, dot_c)
501 }
502 }
503 }
504}
505
506pub mod simplex3 {
508 #[cfg(feature = "derive_serdes")]
509 use serde::{Deserialize, Serialize};
510
511 use crate::*;
512 use crate::geometry::*;
513
514 pub type SegmentPoint <S> = (Normalized <S>, Point3 <S>);
516 pub type TrianglePoint <S> = ([Normalized <S>; 2], Point3 <S>);
518 pub type TetrahedronPoint <S> = ([Normalized <S>; 3], Point3 <S>);
520
521 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
526 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
527 pub enum Simplex3 <S> {
528 Segment (Segment <S>),
529 Triangle (Triangle <S>),
530 Tetrahedron (Tetrahedron <S>)
531 }
532
533 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
537 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
538 pub struct Segment <S> {
539 a : Point3 <S>,
540 b : Point3 <S>
541 }
542
543 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
547 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
548 pub struct Triangle <S> {
549 a : Point3 <S>,
550 b : Point3 <S>,
551 c : Point3 <S>
552 }
553
554 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
558 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
559 pub struct Tetrahedron <S> {
560 a : Point3 <S>,
561 b : Point3 <S>,
562 c : Point3 <S>,
563 d : Point3 <S>
564 }
565
566 impl_accessors!(Segment, Point3, 2, [(point_a, a), (point_b, b)]);
567 impl_accessors!(Triangle, Point3, 3, [(point_a, a), (point_b, b), (point_c, c)]);
568 impl_accessors!(Tetrahedron, Point3, 4,
569 [(point_a, a), (point_b, b), (point_c, c), (point_d, d)]);
570
571 impl <S : OrderedRing> Segment <S> {
572 pub fn new (a : Point3 <S>, b : Point3 <S>) -> Option <Self> {
579 if a == b {
580 None
581 } else {
582 Some (Segment { a, b })
583 }
584 }
585 pub fn noisy (a : Point3 <S>, b : Point3 <S>) -> Self {
592 assert_ne!(a, b);
593 Segment { a, b }
594 }
595 pub fn unchecked (a : Point3 <S>, b : Point3 <S>) -> Self {
602 debug_assert_ne!(a, b);
603 Segment { a, b }
604 }
605 #[inline]
606 pub fn from_array ([a, b] : [Point3 <S>; 2]) -> Option <Self> {
607 Self::new (a, b)
608 }
609 #[inline]
610 pub fn numcast <T> (self) -> Option <Segment <T>> where
611 S : num::NumCast,
612 T : num::NumCast
613 {
614 Some (Segment {
615 a: self.a.numcast()?,
616 b: self.b.numcast()?
617 })
618 }
619 pub fn point (self, param : Normalized <S>) -> Point3 <S> {
621 self.a + *self.vector() * param
622 }
623 #[inline]
624 pub fn length (self) -> NonNegative <S> where S : Field + Sqrt {
625 self.vector().norm()
626 }
627 #[inline]
628 pub fn length_squared (self) -> NonNegative <S> {
629 self.vector().self_dot()
630 }
631 #[inline]
633 pub fn vector (self) -> NonZero3 <S> {
634 NonZero3::unchecked (self.b - self.a)
635 }
636 #[inline]
638 pub fn perpendicular (self) -> NonZero3 <S> where
639 S : Field + approx::AbsDiffEq <Epsilon = S>
640 {
641 NonZero3::unchecked (self.vector().orthogonal())
642 }
643 #[inline]
644 pub fn midpoint (self) -> Point3 <S> where S : Field {
645 ((self.a.0 + self.b.0) * S::half()).into()
646 }
647 #[inline]
648 pub fn aabb3 (self) -> Aabb3 <S> {
649 Aabb3::from_points_unchecked (self.a, self.b)
650 }
651 #[inline]
652 pub fn line (self) -> Line3 <S> where S : Field + Sqrt {
653 Line3::new (self.a, Unit3::normalize (*self.vector()))
654 }
655 pub fn affine_line (self) -> frame::Line3 <S> {
656 frame::Line3 {
657 origin: self.a,
658 basis: self.vector()
659 }
660 }
661 #[inline]
662 pub fn nearest_point (self, point : Point3 <S>) -> SegmentPoint <S> where
663 S : Field
664 {
665 distance::nearest_segment3_point3 (self, point)
666 }
667 #[inline]
668 pub fn intersect_aabb (self, aabb : Aabb3 <S>)
669 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
670 where S : Real + num::Float + approx::RelativeEq <Epsilon=S> {
671 intersect::intersect_segment3_aabb3 (self, aabb)
672 }
673 #[inline]
674 pub fn intersect_triangle (self, triangle : Triangle3 <S>)
675 -> Option <SegmentPoint <S>>
676 where S : OrderedField + approx::AbsDiffEq <Epsilon=S> {
677 intersect::intersect_segment3_triangle3 (self, triangle)
678 }
679 #[inline]
680 pub fn intersect_sphere (self, sphere : Sphere3 <S>)
681 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
682 where S : Field + Sqrt {
683 intersect::intersect_segment3_sphere3 (self, sphere)
684 }
685 #[inline]
686 pub fn intersect_cylinder (self, sphere : Cylinder3 <S>)
687 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
688 where S : Real {
689 intersect::intersect_segment3_cylinder3 (self, sphere)
690 }
691 #[inline]
692 pub fn intersect_capsule (self, capsule : Capsule3 <S>)
693 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
694 where S : Real {
695 intersect::intersect_segment3_capsule3 (self, capsule)
696 }
697 #[inline]
698 pub fn intersect_hull (self, hull : &Hull3 <S>, mesh : &mesh::VertexEdgeTriangleMesh)
699 -> Option <(SegmentPoint <S>, SegmentPoint <S>)>
700 where S : OrderedField + Sqrt + approx::RelativeEq <Epsilon = S> {
701 intersect::intersect_segment3_hull3 (self, hull, mesh)
702 }
703 }
704 impl <S : Ring> Default for Segment <S> {
705 fn default() -> Self {
716 Segment {
717 a: [-S::one(), S::zero(), S::zero()].into(),
718 b: [ S::one(), S::zero(), S::zero()].into()
719 }
720 }
721 }
722 impl <S> std::ops::Index <usize> for Segment <S> where S : Copy {
723 type Output = Point3 <S>;
724 fn index (&self, index : usize) -> &Point3 <S> {
725 [&self.a, &self.b][index]
726 }
727 }
728 impl <S> TryFrom <[Point3 <S>; 2]> for Segment <S> where S : OrderedRing {
729 type Error = [Point3 <S>; 2];
730 fn try_from ([a, b] : [Point3 <S>; 2]) -> Result <Self, Self::Error> {
731 Self::new (a, b).ok_or([a, b])
732 }
733 }
734 impl <S> Primitive <S, Point3 <S>> for Segment <S> where
735 S : OrderedField + approx::AbsDiffEq
736 {
737 fn translate (&mut self, displacement : Vector3 <S>) {
738 self.a += displacement;
739 self.b += displacement;
740 }
741 fn scale (&mut self, scale : Positive <S>) {
742 let midpoint = self.midpoint();
743 self.translate (-midpoint.0);
744 self.a = Point3 (self.a.0 * scale);
745 self.b = Point3 (self.b.0 * scale);
746 self.translate (midpoint.0);
747 }
748 fn support (&self, direction : NonZero3 <S>) -> (Point3 <S>, S) {
749 let [dot_a, dot_b] = self.points().map (|p| direction.dot (p.0));
750 if dot_a >= dot_b {
751 (self.a, dot_a)
752 } else {
753 (self.b, dot_b)
754 }
755 }
756 }
757
758 impl <S : OrderedField> Triangle <S> {
759 pub fn new (a : Point3 <S>, b : Point3 <S>, c : Point3 <S>) -> Option <Self> where
770 S : Sqrt + approx::RelativeEq <Epsilon = S>
771 {
772 if colinear_3 (a, b, c) {
773 None
774 } else {
775 Some (Triangle { a, b, c })
776 }
777 }
778 pub fn noisy (a : Point3 <S>, b : Point3 <S>, c : Point3 <S>) -> Self where
788 S : Sqrt + approx::RelativeEq <Epsilon = S>
789 {
790 debug_assert_ne!(a, b);
791 debug_assert_ne!(a, c);
792 debug_assert_ne!(b, c);
793 assert!(!colinear_3 (a, b, c));
794 Triangle { a, b, c }
795 }
796 pub fn unchecked (a : Point3 <S>, b : Point3 <S>, c : Point3 <S>) -> Self where
806 S : Sqrt + approx::RelativeEq <Epsilon = S>
807 {
808 debug_assert_ne!(a, b);
809 debug_assert_ne!(a, c);
810 debug_assert_ne!(b, c);
811 debug_assert!(!colinear_3 (a, b, c));
812 Triangle { a, b, c }
813 }
814 #[inline]
815 pub fn from_array ([a, b, c] : [Point3 <S>; 3]) -> Option <Self> where
816 S : Sqrt + approx::RelativeEq <Epsilon = S>
817 {
818 Self::new (a, b, c)
819 }
820 pub fn point (self, s : Normalized <S>, t : Normalized <S>) -> Option <Point3 <S>> {
824 if *s + *t > S::one() {
825 None
826 } else {
827 Some (self.a + (self.b - self.a) * s + (self.c - self.a) * t)
828 }
829 }
830 #[inline]
831 pub const fn edge_ab (self) -> Segment3 <S> {
832 Segment { a: self.a, b: self.b }
833 }
834 #[inline]
835 pub const fn edge_bc (self) -> Segment3 <S> {
836 Segment { a: self.b, b: self.c }
837 }
838 #[inline]
839 pub const fn edge_ca (self) -> Segment3 <S> {
840 Segment { a: self.c, b: self.a }
841 }
842 #[inline]
843 pub const fn edges (self) -> [Segment3 <S>; 3] {
844 [ Segment { a: self.a, b: self.b },
845 Segment { a: self.b, b: self.c },
846 Segment { a: self.c, b: self.a }
847 ]
848 }
849 #[inline]
853 pub const fn rewind (self) -> Self {
854 self.acb()
855 }
856 #[inline]
858 pub const fn acb (self) -> Self {
859 Triangle { a: self.a, b: self.c, c: self.b }
860 }
861 #[inline]
863 pub fn normal (self) -> NonZero3 <S> {
864 let ab = self.b - self.a;
865 let ac = self.c - self.b;
866 NonZero3::unchecked (ab.cross (ac))
867 }
868 #[inline]
870 pub fn unit_normal (self) -> Unit3 <S> where S : Sqrt {
871 self.normal().normalize()
872 }
873 pub fn perpendicular_ab (self) -> NonZero3 <S> {
890 let ab = self.b - self.a;
891 let ac = self.c - self.a;
892 let perp = ab.cross (ab.cross (ac));
893 debug_assert!(perp.dot (ac) < S::zero());
894 NonZero3::unchecked (perp)
895 }
896 pub fn perpendicular_bc (self) -> NonZero3 <S> {
913 let bc = self.c - self.b;
914 let ba = self.a - self.b;
915 let perp = bc.cross (bc.cross (ba));
916 debug_assert!(perp.dot (ba) < S::zero());
917 NonZero3::unchecked (perp)
918 }
919 pub fn perpendicular_ca (self) -> NonZero3 <S> {
936 let ca = self.a - self.c;
937 let cb = self.b - self.c;
938 let perp = ca.cross (ca.cross (cb));
939 debug_assert!(perp.dot (cb) < S::zero());
940 NonZero3::unchecked (perp)
941 }
942 #[inline]
943 pub fn area (self) -> Positive <S> where S : Sqrt {
944 Positive::unchecked (*self.normal().norm() * S::half())
945 }
946 #[inline]
949 pub fn centroid (self) -> Point3 <S> {
950 self.barycentric (Vector3::broadcast (S::one() / S::three()))
951 }
952 #[inline]
955 pub fn incenter (self) -> Point3 <S> where S : Real + num::real::Real {
956 self.trilinear (Vector3::one())
957 }
958 pub fn barycentric (self, coords : Vector3 <S>) -> Point3 <S> {
959 (self.a.0 * coords.x + self.b.0 * coords.y + self.c.0 * coords.z).into()
960 }
961 pub fn trilinear (self, coords : Vector3 <S>) -> Point3 <S> where
962 S : Real + num::real::Real
963 {
964 let (ab, bc, ca) = (self.b - self.a, self.c - self.b, self.a - self.c);
965 let len_ab = ab.magnitude();
966 let len_bc = bc.magnitude();
967 let len_ca = ca.magnitude();
968 let ax = len_bc * coords.x;
969 let by = len_ca * coords.y;
970 let cz = len_ab * coords.z;
971 let denom = S::one() / (ax + by + cz);
972 (self.a.0 * ax * denom + self.b.0 * by * denom + self.c.0 * cz * denom).into()
973 }
974 #[inline]
975 pub fn affine_plane (self) -> frame::Plane3 <S> {
976 frame::Plane3 {
977 origin: self.a,
978 basis: frame::PlanarBasis3::new ([
979 (self.b - self.a),
980 (self.c - self.a)
981 ].map (NonZero3::unchecked)).unwrap()
982 }
983 }
984 #[inline]
985 pub fn nearest_point (self, point : Point3 <S>) -> TrianglePoint <S> {
986 distance::nearest_triangle3_point3 (self, point)
987 }
988 }
989 impl <S : Field + Sqrt> Default for Triangle <S> {
990 fn default() -> Self {
1017 let frac_1_sqrt_2 = S::one() / (S::one() + S::one()).sqrt();
1018 Triangle {
1019 a: [ S::zero(), S::one(), S::zero()].into(),
1020 b: [-frac_1_sqrt_2, -frac_1_sqrt_2, S::zero()].into(),
1021 c: [ frac_1_sqrt_2, -frac_1_sqrt_2, S::zero()].into()
1022 }
1023 }
1024 }
1025 impl <S> std::ops::Index <usize> for Triangle <S> where S : Copy {
1026 type Output = Point3 <S>;
1027 fn index (&self, index : usize) -> &Point3 <S> {
1028 [&self.a, &self.b, &self.c][index]
1029 }
1030 }
1031 impl <S> TryFrom <[Point3 <S>; 3]> for Triangle <S> where
1032 S : OrderedField + Sqrt + approx::RelativeEq <Epsilon = S>
1033 {
1034 type Error = [Point3 <S>; 3];
1035 fn try_from ([a, b, c] : [Point3 <S>; 3]) -> Result <Self, Self::Error> {
1036 Self::new (a, b, c).ok_or([a, b, c])
1037 }
1038 }
1039 impl <S> Primitive <S, Point3 <S>> for Triangle <S> where
1040 S : OrderedField + approx::AbsDiffEq
1041 {
1042 fn translate (&mut self, displacement : Vector3 <S>) {
1043 self.a += displacement;
1044 self.b += displacement;
1045 self.c += displacement;
1046 }
1047 fn scale (&mut self, scale : Positive <S>) {
1048 let centroid = self.centroid();
1049 self.translate (-centroid.0);
1050 self.a = Point3 (self.a.0 * scale);
1051 self.b = Point3 (self.b.0 * scale);
1052 self.c = Point3 (self.c.0 * scale);
1053 self.translate (centroid.0);
1054 }
1055 fn support (&self, direction : NonZero3 <S>) -> (Point3 <S>, S) {
1056 let [dot_a, dot_b, dot_c] = self.points().map (|p| direction.dot (p.0));
1057 if dot_a >= dot_b && dot_a >= dot_c {
1058 (self.a, dot_a)
1059 } else if dot_b >= dot_c {
1060 (self.b, dot_b)
1061 } else {
1062 (self.c, dot_c)
1063 }
1064 }
1065 }
1066
1067 impl <S : OrderedField> Tetrahedron <S> {
1068 pub fn new (a : Point3 <S>, b : Point3 <S>, c : Point3 <S>, d : Point3 <S>)
1080 -> Option <Self>
1081 where S : approx::AbsDiffEq <Epsilon = S> {
1082 if coplanar_3 (a, b, c, d) {
1083 None
1084 } else {
1085 Some (Tetrahedron { a, b, c, d })
1086 }
1087 }
1088 pub fn noisy (a : Point3 <S>, b : Point3 <S>, c : Point3 <S>, d : Point3 <S>)
1099 -> Self
1100 where S : approx::AbsDiffEq <Epsilon = S> {
1101 assert!(!coplanar_3 (a, b, c, d));
1102 Tetrahedron { a, b, c, d }
1103 }
1104 pub fn unchecked (a : Point3 <S>, b : Point3 <S>, c : Point3 <S>, d : Point3 <S>)
1115 -> Self
1116 where S : approx::AbsDiffEq <Epsilon = S> {
1117 debug_assert!(!coplanar_3 (a, b, c, d));
1118 Tetrahedron { a, b, c, d }
1119 }
1120 #[inline]
1121 pub fn from_array ([a, b, c, d] : [Point3 <S>; 4]) -> Option <Self> where
1122 S : approx::AbsDiffEq <Epsilon = S>
1123 {
1124 Self::new (a, b, c, d)
1125 }
1126 #[inline]
1127 pub const fn edge_ab (self) -> Segment3 <S> {
1128 Segment { a: self.a, b: self.b }
1129 }
1130 #[inline]
1131 pub const fn edge_ac (self) -> Segment3 <S> {
1132 Segment { a: self.a, b: self.c }
1133 }
1134 #[inline]
1135 pub const fn edge_ad (self) -> Segment3 <S> {
1136 Segment { a: self.a, b: self.d }
1137 }
1138 #[inline]
1139 pub const fn edge_bc (self) -> Segment3 <S> {
1140 Segment { a: self.b, b: self.c }
1141 }
1142 #[inline]
1143 pub const fn edge_bd (self) -> Segment3 <S> {
1144 Segment { a: self.b, b: self.d }
1145 }
1146 #[inline]
1147 pub const fn edge_cd (self) -> Segment3 <S> {
1148 Segment { a: self.c, b: self.d }
1149 }
1150 #[inline]
1151 pub const fn edges (self) -> [Segment3 <S>; 6] {
1152 [ self.edge_ab(),
1153 self.edge_ac(),
1154 self.edge_ad(),
1155 self.edge_bc(),
1156 self.edge_bd(),
1157 self.edge_cd()
1158 ]
1159 }
1160 #[inline]
1163 pub fn face_abc (self) -> Triangle <S> {
1164 let triangle = Triangle { a: self.a, b: self.b, c: self.c };
1165 if triangle.normal().dot (self.d - self.a) > S::zero() {
1166 triangle.rewind()
1167 } else {
1168 triangle
1169 }
1170 }
1171 #[inline]
1174 pub fn face_abd (self) -> Triangle <S> {
1175 let triangle = Triangle { a: self.a, b: self.b, c: self.d };
1176 if triangle.normal().dot (self.c - self.a) > S::zero() {
1177 triangle.rewind()
1178 } else {
1179 triangle
1180 }
1181 }
1182 #[inline]
1185 pub fn face_acd (self) -> Triangle <S> {
1186 let triangle = Triangle { a: self.a, b: self.c, c: self.d };
1187 if triangle.normal().dot (self.b - self.a) > S::zero() {
1188 triangle.rewind()
1189 } else {
1190 triangle
1191 }
1192 }
1193 #[inline]
1196 pub fn face_bcd (self) -> Triangle <S> {
1197 let triangle = Triangle { a: self.b, b: self.c, c: self.d };
1198 if triangle.normal().dot (self.a - self.b) > S::zero() {
1199 triangle.rewind()
1200 } else {
1201 triangle
1202 }
1203 }
1204 #[inline]
1205 pub fn faces (self) -> [Triangle <S>; 4] {
1206 [ self.face_abc(),
1207 self.face_abd(),
1208 self.face_acd(),
1209 self.face_bcd()
1210 ]
1211 }
1212 pub fn normal_abc (self) -> NonZero3 <S> {
1213 let mut abc_normal = self.face_abc().normal();
1214 let ad = self.d - self.a;
1215 if abc_normal.dot (ad) > S::zero() {
1216 abc_normal = -abc_normal;
1217 }
1218 abc_normal
1219 }
1220 pub fn normal_abd (self) -> NonZero3 <S> {
1221 let mut abd_normal = self.face_abd().normal();
1222 let ac = self.c - self.a;
1223 if abd_normal.dot (ac) > S::zero() {
1224 abd_normal = -abd_normal;
1225 }
1226 abd_normal
1227 }
1228 pub fn normal_acd (self) -> NonZero3 <S> {
1229 let mut acd_normal = self.face_acd().normal();
1230 let ab = self.b - self.a;
1231 if acd_normal.dot (ab) > S::zero() {
1232 acd_normal = -acd_normal;
1233 }
1234 acd_normal
1235 }
1236 pub fn normal_bcd (self) -> NonZero3 <S> {
1237 let mut bcd_normal = self.face_bcd().normal();
1238 let ba = self.a - self.b;
1239 if bcd_normal.dot (ba) > S::zero() {
1240 bcd_normal = -bcd_normal;
1241 }
1242 bcd_normal
1243 }
1244 pub fn volume (self) -> Positive <S> {
1245 Positive::unchecked (
1246 (self.b - self.a).cross (self.c - self.a).dot (self.d - self.a).abs()
1247 * (S::one() / S::six()))
1248 }
1249 #[inline]
1250 pub fn centroid (self) -> Point3 <S> {
1251 Point3 ((self.a.0 + self.b.0 + self.c.0 + self.d.0) / S::four())
1252 }
1253 #[inline]
1268 pub fn contains (self, point : Point3 <S>) -> bool {
1269 let ap = point - self.a;
1270 let bp = point - self.b;
1271 self.normal_abc().dot (ap) < S::zero() &&
1272 self.normal_abd().dot (ap) < S::zero() &&
1273 self.normal_acd().dot (ap) < S::zero() &&
1274 self.normal_bcd().dot (bp) < S::zero()
1275 }
1276 }
1277 impl <S : Field + Sqrt> Default for Tetrahedron <S> {
1278 fn default() -> Self {
1309 let frac_1_3 = S::one() / S::three();
1310 let sqrt_2_3 = (S::two() / S::three()).sqrt();
1311 let sqrt_8_9 = (S::eight() / S::nine()).sqrt();
1312 let sqrt_2_9 = (S::two() / S::nine()).sqrt();
1313 Tetrahedron {
1314 a: [S::zero(), S::zero(), S::one()].into(),
1315 b: [S::zero(), sqrt_8_9, -frac_1_3].into(),
1316 c: [ sqrt_2_3, -sqrt_2_9, -frac_1_3].into(),
1317 d: [-sqrt_2_3, -sqrt_2_9, -frac_1_3].into()
1318 }
1319 }
1320 }
1321 impl <S> std::ops::Index <usize> for Tetrahedron <S> where S : Copy {
1322 type Output = Point3 <S>;
1323 fn index (&self, index : usize) -> &Point3 <S> {
1324 [&self.a, &self.b, &self.c, &self.d][index]
1325 }
1326 }
1327 impl <S> TryFrom <[Point3 <S>; 4]> for Tetrahedron <S> where
1328 S : OrderedField + approx::RelativeEq <Epsilon = S>
1329 {
1330 type Error = [Point3 <S>; 4];
1331 fn try_from ([a, b, c, d] : [Point3 <S>; 4]) -> Result <Self, Self::Error> {
1332 Self::new (a, b, c, d).ok_or([a, b, c, d])
1333 }
1334 }
1335 impl <S> Primitive <S, Point3 <S>> for Tetrahedron <S> where
1336 S : OrderedField + approx::AbsDiffEq
1337 {
1338 fn translate (&mut self, displacement : Vector3 <S>) {
1339 self.a += displacement;
1340 self.b += displacement;
1341 self.c += displacement;
1342 self.d += displacement;
1343 }
1344 fn scale (&mut self, scale : Positive <S>) {
1345 let centroid = self.centroid();
1346 self.translate (-centroid.0);
1347 self.a = Point3 (self.a.0 * scale);
1348 self.b = Point3 (self.b.0 * scale);
1349 self.c = Point3 (self.c.0 * scale);
1350 self.d = Point3 (self.d.0 * scale);
1351 self.translate (centroid.0);
1352 }
1353 fn support (&self, direction : NonZero3 <S>) -> (Point3 <S>, S) {
1354 let [dot_a, dot_b, dot_c, dot_d] = self.points().map (|p| direction.dot (p.0));
1355 if dot_a >= dot_b && dot_a >= dot_c && dot_a >= dot_d {
1356 (self.a, dot_a)
1357 } else if dot_b >= dot_c && dot_b >= dot_d {
1358 (self.b, dot_b)
1359 } else if dot_c >= dot_d {
1360 (self.c, dot_c)
1361 } else {
1362 (self.d, dot_d)
1363 }
1364 }
1365 }
1366}
1367
1368#[cfg(test)]
1369mod tests {
1370 use crate::*;
1371 use crate::geometry::*;
1372 use super::*;
1373
1374 #[test]
1375 fn barycentric_2d() {
1376 let triangle = simplex2::Triangle::noisy (
1377 [-2.0, -2.0].into(), [2.0, -2.0].into(), [0.0, 2.0].into());
1378 assert_eq!(triangle.barycentric ([1.0, 0.0, 0.0].into()), [-2.0, -2.0].into());
1379 assert_eq!(triangle.barycentric ([0.0, 1.0, 0.0].into()), [ 2.0, -2.0].into());
1380 assert_eq!(triangle.barycentric ([0.0, 0.0, 1.0].into()), [ 0.0, 2.0].into());
1381 assert_eq!(triangle.barycentric ([0.5, 0.5, 0.0].into()), [ 0.0, -2.0].into());
1382 assert_eq!(triangle.barycentric ([0.5, 0.0, 0.5].into()), [-1.0, 0.0].into());
1383 assert_eq!(triangle.barycentric ([0.0, 0.5, 0.5].into()), [ 1.0, 0.0].into());
1384 }
1385
1386 #[test]
1387 fn barycentric_3d() {
1388 let triangle = simplex3::Triangle::noisy (
1389 [-2.0, -2.0, 0.0].into(), [2.0, -2.0, 0.0].into(), [0.0, 2.0, 0.0].into());
1390 assert_eq!(triangle.barycentric ([1.0, 0.0, 0.0].into()), [-2.0, -2.0, 0.0].into());
1391 assert_eq!(triangle.barycentric ([0.0, 1.0, 0.0].into()), [ 2.0, -2.0, 0.0].into());
1392 assert_eq!(triangle.barycentric ([0.0, 0.0, 1.0].into()), [ 0.0, 2.0, 0.0].into());
1393 assert_eq!(triangle.barycentric ([0.5, 0.5, 0.0].into()), [ 0.0, -2.0, 0.0].into());
1394 assert_eq!(triangle.barycentric ([0.5, 0.0, 0.5].into()), [-1.0, 0.0, 0.0].into());
1395 assert_eq!(triangle.barycentric ([0.0, 0.5, 0.5].into()), [ 1.0, 0.0, 0.0].into());
1396 }
1397
1398 #[test]
1399 fn trilinear_2d() {
1400 let triangle = simplex2::Triangle::noisy (
1401 [-2.0, -2.0].into(), [2.0, -2.0].into(), [0.0, 2.0].into());
1402 assert_eq!(triangle.trilinear ([1.0, 0.0, 0.0].into()), [-2.0, -2.0].into());
1403 assert_eq!(triangle.trilinear ([0.0, 1.0, 0.0].into()), [ 2.0, -2.0].into());
1404 assert_eq!(triangle.trilinear ([0.0, 0.0, 1.0].into()), [ 0.0, 2.0].into());
1405 assert_eq!(triangle.trilinear (
1407 [1.0 / 20.0f32.sqrt(), 1.0 / 20.0f32.sqrt(), 0.25].into()),
1408 [0.0, -2.0/3.0].into());
1409 approx::assert_relative_eq!(triangle.trilinear (
1411 [1.0, 1.0, 1.0].into()),
1412 [ 0.0, 5.0f32.sqrt() - 3.0].into());
1413 }
1414
1415 #[test]
1416 fn trilinear_3d() {
1417 let triangle = simplex3::Triangle::noisy (
1418 [-2.0, -2.0, 0.0].into(), [2.0, -2.0, 0.0].into(), [0.0, 2.0, 0.0].into());
1419 assert_eq!(triangle.trilinear ([1.0, 0.0, 0.0].into()), [-2.0, -2.0, 0.0].into());
1420 assert_eq!(triangle.trilinear ([0.0, 1.0, 0.0].into()), [ 2.0, -2.0, 0.0].into());
1421 assert_eq!(triangle.trilinear ([0.0, 0.0, 1.0].into()), [ 0.0, 2.0, 0.0].into());
1422 assert_eq!(triangle.trilinear (
1424 [1.0 / 20.0f32.sqrt(), 1.0 / 20.0f32.sqrt(), 0.25].into()),
1425 [0.0, -2.0/3.0, 0.0].into());
1426 approx::assert_relative_eq!(triangle.trilinear (
1428 [1.0, 1.0, 1.0].into()),
1429 [ 0.0, 5.0f32.sqrt() - 3.0, 0.0].into());
1430 }
1431
1432 #[test]
1433 fn scale() {
1434 let mut s = simplex2::Segment::noisy (point!(-2.0, 2.0), point!(2.0, 2.0));
1435 s.scale (Positive::noisy (0.5));
1436 assert_eq!(s.point_a(), point!(-1.0, 2.0));
1437 assert_eq!(s.point_b(), point!( 1.0, 2.0));
1438 }
1439
1440 #[test]
1441 fn tetrahedron_face_normals() {
1442 use rand;
1444 use rand_xorshift::XorShiftRng;
1445 use rand::SeedableRng;
1446 let aabb = Aabb3::<f32>::with_minmax_unchecked (
1447 [-10.0, -10.0, -10.0].into(),
1448 [ 10.0, 10.0, 10.0].into());
1449 let mut rng = XorShiftRng::seed_from_u64 (0);
1450 for _ in 0..10000 {
1451 let t = Tetrahedron3::noisy (
1452 aabb.rand_point (&mut rng),
1453 aabb.rand_point (&mut rng),
1454 aabb.rand_point (&mut rng),
1455 aabb.rand_point (&mut rng));
1456 for face in t.faces() {
1457 let other_p = {
1458 let mut point = None;
1459 for p in t.points() {
1460 if !face.points().contains (&p) {
1461 point = Some (p);
1462 break
1463 }
1464 }
1465 point.unwrap()
1466 };
1467 assert!(face.normal().dot (other_p - face.point_a()) < 0.0);
1468 }
1469 }
1470 }
1471}