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 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
17 #[derive(Clone, Copy, Debug, PartialEq)]
18 pub enum Simplex2 <S> {
19 Segment (Segment <S>),
20 Triangle (Triangle <S>)
21 }
22
23 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
28 #[derive(Clone, Copy, Debug, PartialEq)]
29 pub struct Segment <S> {
30 a : Point2 <S>,
31 b : Point2 <S>
32 }
33
34 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
39 #[derive(Clone, Copy, Debug, PartialEq)]
40 pub struct Triangle <S> {
41 a : Point2 <S>,
42 b : Point2 <S>,
43 c : Point2 <S>
44 }
45
46 impl <S : Ring> Segment <S> {
47 pub fn new (
54 a : Point2 <S>,
55 b : Point2 <S>
56 ) -> Self where S : std::fmt::Debug {
57 assert_ne!(a, b);
58 Segment { a, b }
59 }
60 pub fn unchecked (
67 a : Point2 <S>,
68 b : Point2 <S>
69 ) -> Self where S : std::fmt::Debug {
70 debug_assert_ne!(a, b);
71 Segment { a, b }
72 }
73 #[inline]
74 pub fn numcast <T> (self) -> Option <Segment <T>> where
75 S : num_traits::NumCast,
76 T : num_traits::NumCast
77 {
78 Some (Segment {
79 a: self.a.numcast()?,
80 b: self.b.numcast()?
81 })
82 }
83 #[inline]
84 pub fn point_a (&self) -> &Point2 <S> {
85 &self.a
86 }
87 #[inline]
88 pub fn point_b (&self) -> &Point2 <S> {
89 &self.b
90 }
91 #[inline]
92 pub fn length (&self) -> S where S : Field + Sqrt {
93 self.vector().norm()
94 }
95 #[inline]
96 pub fn length2 (&self) -> S {
97 self.vector().self_dot()
98 }
99 #[inline]
101 pub fn vector (&self) -> Vector2 <S> {
102 self.b - self.a
103 }
104 #[inline]
105 pub fn aabb2 (&self) -> Aabb2 <S> where S : std::fmt::Debug {
106 Aabb2::from_points (self.a, self.b)
107 }
108 #[inline]
109 pub fn line2 (&self) -> Line2 <S> where S : Real {
110 Line2::new (self.a, Unit2::normalize (self.vector()))
111 }
112 #[inline]
113 #[allow(clippy::type_complexity)]
114 pub fn intersect_aabb (&self, aabb : &Aabb2 <S>)
115 -> Option <((S, Point2 <S>), (S, Point2 <S>))>
116 where S : Real + std::fmt::Debug {
117 intersect::continuous_segment2_aabb2 (self, aabb)
118 }
119 #[inline]
120 #[allow(clippy::type_complexity)]
121 pub fn intersect_sphere (&self, sphere : &Sphere2 <S>)
122 -> Option <((S, Point2 <S>), (S, Point2 <S>))>
123 where S : Real + std::fmt::Debug {
124 intersect::continuous_segment2_sphere2 (self, sphere)
125 }
126 }
127 impl <S : Field> Default for Segment <S> {
128 fn default() -> Self {
139 Segment {
140 a: [-S::one(), S::zero()].into(),
141 b: [ S::one(), S::zero()].into()
142 }
143 }
144 }
145
146 impl <S : Field> Triangle <S> {
147 pub fn new (
157 a : Point2 <S>,
158 b : Point2 <S>,
159 c : Point2 <S>
160 ) -> Self where S : approx::RelativeEq + std::fmt::Debug {
161 debug_assert_ne!(a, b);
162 debug_assert_ne!(a, c);
163 debug_assert_ne!(b, c);
164 assert!(!colinear_2d (&a, &b, &c));
165 Triangle { a, b, c }
166 }
167 pub fn unchecked (
177 a : Point2 <S>,
178 b : Point2 <S>,
179 c : Point2 <S>
180 ) -> Self where S : approx::RelativeEq + std::fmt::Debug {
181 debug_assert_ne!(a, b);
182 debug_assert_ne!(a, c);
183 debug_assert_ne!(b, c);
184 debug_assert!(!colinear_2d (&a, &b, &c));
185 Triangle { a, b, c }
186 }
187 #[inline]
188 pub fn point_a (&self) -> &Point2 <S> {
189 &self.a
190 }
191 #[inline]
192 pub fn point_b (&self) -> &Point2 <S> {
193 &self.b
194 }
195 #[inline]
196 pub fn point_c (&self) -> &Point2 <S> {
197 &self.c
198 }
199 }
200 impl <S : Field + Sqrt> Default for Triangle <S> {
201 fn default() -> Self {
219 let frac_1_sqrt_2 = S::one() / (S::one() + S::one()).sqrt();
220 Triangle {
221 a: [ S::zero(), S::one()].into(),
222 b: [-frac_1_sqrt_2, -frac_1_sqrt_2].into(),
223 c: [ frac_1_sqrt_2, -frac_1_sqrt_2].into()
224 }
225 }
226 }
227}
228
229pub mod simplex3 {
231 #[cfg(feature = "derive_serdes")]
232 use serde::{Deserialize, Serialize};
233
234 use crate::*;
235 use crate::geometry::*;
236 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
241 #[derive(Clone, Copy, Debug, PartialEq)]
242 pub enum Simplex3 <S> {
243 Segment (Segment <S>),
244 Triangle (Triangle <S>),
245 Tetrahedron (Tetrahedron <S>)
246 }
247
248 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
253 #[derive(Clone, Copy, Debug, PartialEq)]
254 pub struct Segment <S> {
255 a : Point3 <S>,
256 b : Point3 <S>
257 }
258
259 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
264 #[derive(Clone, Copy, Debug, PartialEq)]
265 pub struct Triangle <S> {
266 a : Point3 <S>,
267 b : Point3 <S>,
268 c : Point3 <S>
269 }
270
271 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
276 #[derive(Clone, Copy, Debug, PartialEq)]
277 pub struct Tetrahedron <S> {
278 a : Point3 <S>,
279 b : Point3 <S>,
280 c : Point3 <S>,
281 d : Point3 <S>
282 }
283
284 impl <S : Ring> Segment <S> {
285 pub fn new (
292 a : Point3 <S>,
293 b : Point3 <S>
294 ) -> Self where S : std::fmt::Debug {
295 assert_ne!(a, b);
296 Segment { a, b }
297 }
298 pub fn unchecked (
305 a : Point3 <S>,
306 b : Point3 <S>
307 ) -> Self where S : std::fmt::Debug {
308 debug_assert_ne!(a, b);
309 Segment { a, b }
310 }
311 #[inline]
312 pub fn numcast <T> (self) -> Option <Segment <T>> where
313 S : num_traits::NumCast,
314 T : num_traits::NumCast
315 {
316 Some (Segment {
317 a: self.a.numcast()?,
318 b: self.b.numcast()?
319 })
320 }
321 #[inline]
322 pub fn point_a (&self) -> &Point3 <S> {
323 &self.a
324 }
325 #[inline]
326 pub fn point_b (&self) -> &Point3 <S> {
327 &self.b
328 }
329 #[inline]
330 pub fn length (&self) -> S where S : Field + Sqrt {
331 self.vector().norm()
332 }
333 #[inline]
334 pub fn length2 (&self) -> S {
335 self.vector().self_dot()
336 }
337 #[inline]
339 pub fn vector (&self) -> Vector3 <S> {
340 self.b - self.a
341 }
342 #[inline]
343 pub fn aabb3 (&self) -> Aabb3 <S> where S : std::fmt::Debug {
344 Aabb3::from_points (self.a, self.b)
345 }
346 #[inline]
347 pub fn line3 (&self) -> Line3 <S> where S : Real {
348 Line3::new (self.a, Unit3::normalize (self.vector()))
349 }
350 #[inline]
351 #[allow(clippy::type_complexity)]
352 pub fn intersect_aabb (&self, aabb : &Aabb3 <S>)
353 -> Option <((S, Point3 <S>), (S, Point3 <S>))>
354 where S : Real + num_traits::Float + approx::RelativeEq <Epsilon=S> +
355 std::fmt::Debug
356 {
357 intersect::continuous_segment3_aabb3 (self, aabb)
358 }
359 #[inline]
360 #[allow(clippy::type_complexity)]
361 pub fn intersect_sphere (&self, sphere : &Sphere3 <S>)
362 -> Option <((S, Point3 <S>), (S, Point3 <S>))>
363 where S : Field + Sqrt {
364 intersect::continuous_segment3_sphere3 (self, sphere)
365 }
366 #[inline]
367 #[allow(clippy::type_complexity)]
368 pub fn intersect_cylinder (&self, sphere : &Cylinder3 <S>)
369 -> Option <((S, Point3 <S>), (S, Point3 <S>))>
370 where S : Real + std::fmt::Debug {
371 intersect::continuous_segment3_cylinder3 (self, sphere)
372 }
373 #[inline]
374 #[allow(clippy::type_complexity)]
375 pub fn intersect_capsule (&self, capsule : &Capsule3 <S>)
376 -> Option <((S, Point3 <S>), (S, Point3 <S>))>
377 where S : Real + std::fmt::Debug {
378 intersect::continuous_segment3_capsule3 (self, capsule)
379 }
380 }
381 impl <S : Field> Default for Segment <S> {
382 fn default() -> Self {
393 Segment {
394 a: [-S::one(), S::zero(), S::zero()].into(),
395 b: [ S::one(), S::zero(), S::zero()].into()
396 }
397 }
398 }
399
400 impl <S : Ring> Triangle <S> {
401 pub fn new (
411 a : Point3 <S>,
412 b : Point3 <S>,
413 c : Point3 <S>
414 ) -> Self where
415 S : Field + Sqrt + approx::RelativeEq + std::fmt::Debug
416 {
417 debug_assert_ne!(a, b);
418 debug_assert_ne!(a, c);
419 debug_assert_ne!(b, c);
420 assert!(!colinear_3d (&a, &b, &c));
421 Triangle { a, b, c }
422 }
423 pub fn unchecked (
433 a : Point3 <S>,
434 b : Point3 <S>,
435 c : Point3 <S>
436 ) -> Self where
437 S : Field + Sqrt + approx::RelativeEq + std::fmt::Debug
438 {
439 debug_assert_ne!(a, b);
440 debug_assert_ne!(a, c);
441 debug_assert_ne!(b, c);
442 debug_assert!(!colinear_3d (&a, &b, &c));
443 Triangle { a, b, c }
444 }
445 #[inline]
446 pub fn point_a (&self) -> &Point3 <S> {
447 &self.a
448 }
449 #[inline]
450 pub fn point_b (&self) -> &Point3 <S> {
451 &self.b
452 }
453 #[inline]
454 pub fn point_c (&self) -> &Point3 <S> {
455 &self.c
456 }
457 }
458 impl <S : Field + Sqrt> Default for Triangle <S> {
459 fn default() -> Self {
486 let frac_1_sqrt_2 = S::one() / (S::one() + S::one()).sqrt();
487 Triangle {
488 a: [ S::zero(), S::one(), S::zero()].into(),
489 b: [-frac_1_sqrt_2, -frac_1_sqrt_2, S::zero()].into(),
490 c: [ frac_1_sqrt_2, -frac_1_sqrt_2, S::zero()].into()
491 }
492 }
493 }
494
495 impl <S : Ring> Tetrahedron <S> {
496 pub fn new (
507 a : Point3 <S>,
508 b : Point3 <S>,
509 c : Point3 <S>,
510 d : Point3 <S>
511 ) -> Self where
512 S : approx::RelativeEq
513 {
514 assert!(!coplanar_3d (&a, &b, &c, &d));
515 Tetrahedron { a, b, c, d }
516 }
517 pub fn unchecked (
528 a : Point3 <S>,
529 b : Point3 <S>,
530 c : Point3 <S>,
531 d : Point3 <S>
532 ) -> Self where
533 S : approx::RelativeEq
534 {
535 debug_assert!(!coplanar_3d (&a, &b, &c, &d));
536 Tetrahedron { a, b, c, d }
537 }
538 #[inline]
539 pub fn point_a (&self) -> &Point3 <S> {
540 &self.a
541 }
542 #[inline]
543 pub fn point_b (&self) -> &Point3 <S> {
544 &self.b
545 }
546 #[inline]
547 pub fn point_c (&self) -> &Point3 <S> {
548 &self.c
549 }
550 #[inline]
551 pub fn point_d (&self) -> &Point3 <S> {
552 &self.d
553 }
554 }
555 impl <S : Field + Sqrt> Default for Tetrahedron <S> {
556 fn default() -> Self {
587 let frac_1_3 = S::one() / S::three();
588 let sqrt_2_3 = (S::two() / S::three()).sqrt();
589 let sqrt_8_9 = (S::eight() / S::nine()).sqrt();
590 let sqrt_2_9 = (S::two() / S::nine()).sqrt();
591 Tetrahedron {
592 a: [S::zero(), S::zero(), S::one()].into(),
593 b: [S::zero(), sqrt_8_9, -frac_1_3].into(),
594 c: [ sqrt_2_3, -sqrt_2_9, -frac_1_3].into(),
595 d: [-sqrt_2_3, -sqrt_2_9, -frac_1_3].into()
596 }
597 }
598 }
599}