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 pub fn intersect_aabb (&self, aabb : &Aabb2 <S>)
114 -> Option <((S, Point2 <S>), (S, Point2 <S>))>
115 where
116 S : Real + std::fmt::Debug
117 {
118 intersect::continuous_segment2_aabb2 (self, aabb)
119 }
120 #[inline]
121 pub fn intersect_sphere (&self, sphere : &Sphere2 <S>)
122 -> Option <((S, Point2 <S>), (S, Point2 <S>))>
123 where
124 S : Real + std::fmt::Debug
125 {
126 intersect::continuous_segment2_sphere2 (self, sphere)
127 }
128 }
129 impl <S : Field> Default for Segment <S> {
130 fn default() -> Self {
141 Segment {
142 a: [-S::one(), S::zero()].into(),
143 b: [ S::one(), S::zero()].into()
144 }
145 }
146 }
147
148 impl <S : Field> Triangle <S> {
149 pub fn new (
159 a : Point2 <S>,
160 b : Point2 <S>,
161 c : Point2 <S>
162 ) -> Self where S : approx::RelativeEq + std::fmt::Debug {
163 debug_assert_ne!(a, b);
164 debug_assert_ne!(a, c);
165 debug_assert_ne!(b, c);
166 assert!(!colinear_2d (&a, &b, &c));
167 Triangle { a, b, c }
168 }
169 pub fn unchecked (
179 a : Point2 <S>,
180 b : Point2 <S>,
181 c : Point2 <S>
182 ) -> Self where S : approx::RelativeEq + std::fmt::Debug {
183 debug_assert_ne!(a, b);
184 debug_assert_ne!(a, c);
185 debug_assert_ne!(b, c);
186 debug_assert!(!colinear_2d (&a, &b, &c));
187 Triangle { a, b, c }
188 }
189 #[inline]
190 pub fn point_a (&self) -> &Point2 <S> {
191 &self.a
192 }
193 #[inline]
194 pub fn point_b (&self) -> &Point2 <S> {
195 &self.b
196 }
197 #[inline]
198 pub fn point_c (&self) -> &Point2 <S> {
199 &self.c
200 }
201 }
202 impl <S : Field + Sqrt> Default for Triangle <S> {
203 fn default() -> Self {
221 let frac_1_sqrt_2 = S::one() / (S::one() + S::one()).sqrt();
222 Triangle {
223 a: [ S::zero(), S::one()].into(),
224 b: [-frac_1_sqrt_2, -frac_1_sqrt_2].into(),
225 c: [ frac_1_sqrt_2, -frac_1_sqrt_2].into()
226 }
227 }
228 }
229}
230
231pub mod simplex3 {
233 #[cfg(feature = "derive_serdes")]
234 use serde::{Deserialize, Serialize};
235
236 use crate::*;
237 use crate::geometry::*;
238 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
243 #[derive(Clone, Copy, Debug, PartialEq)]
244 pub enum Simplex3 <S> {
245 Segment (Segment <S>),
246 Triangle (Triangle <S>),
247 Tetrahedron (Tetrahedron <S>)
248 }
249
250 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
255 #[derive(Clone, Copy, Debug, PartialEq)]
256 pub struct Segment <S> {
257 a : Point3 <S>,
258 b : Point3 <S>
259 }
260
261 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
266 #[derive(Clone, Copy, Debug, PartialEq)]
267 pub struct Triangle <S> {
268 a : Point3 <S>,
269 b : Point3 <S>,
270 c : Point3 <S>
271 }
272
273 #[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
278 #[derive(Clone, Copy, Debug, PartialEq)]
279 pub struct Tetrahedron <S> {
280 a : Point3 <S>,
281 b : Point3 <S>,
282 c : Point3 <S>,
283 d : Point3 <S>
284 }
285
286 impl <S : Ring> Segment <S> {
287 pub fn new (
294 a : Point3 <S>,
295 b : Point3 <S>
296 ) -> Self where S : std::fmt::Debug {
297 assert_ne!(a, b);
298 Segment { a, b }
299 }
300 pub fn unchecked (
307 a : Point3 <S>,
308 b : Point3 <S>
309 ) -> Self where S : std::fmt::Debug {
310 debug_assert_ne!(a, b);
311 Segment { a, b }
312 }
313 #[inline]
314 pub fn numcast <T> (self) -> Option <Segment <T>> where
315 S : num_traits::NumCast,
316 T : num_traits::NumCast
317 {
318 Some (Segment {
319 a: self.a.numcast()?,
320 b: self.b.numcast()?
321 })
322 }
323 #[inline]
324 pub fn point_a (&self) -> &Point3 <S> {
325 &self.a
326 }
327 #[inline]
328 pub fn point_b (&self) -> &Point3 <S> {
329 &self.b
330 }
331 #[inline]
332 pub fn length (&self) -> S where S : Field + Sqrt {
333 self.vector().norm()
334 }
335 #[inline]
336 pub fn length2 (&self) -> S {
337 self.vector().self_dot()
338 }
339 #[inline]
341 pub fn vector (&self) -> Vector3 <S> {
342 self.b - self.a
343 }
344 #[inline]
345 pub fn aabb3 (&self) -> Aabb3 <S> where S : std::fmt::Debug {
346 Aabb3::from_points (self.a, self.b)
347 }
348 #[inline]
349 pub fn line3 (&self) -> Line3 <S> where S : Real {
350 Line3::new (self.a, Unit3::normalize (self.vector()))
351 }
352 #[inline]
353 pub fn intersect_aabb (&self, aabb : &Aabb3 <S>)
354 -> Option <((S, Point3 <S>), (S, Point3 <S>))>
355 where
356 S : Real + num_traits::Float + approx::RelativeEq <Epsilon=S> +
357 std::fmt::Debug
358 {
359 intersect::continuous_segment3_aabb3 (self, aabb)
360 }
361 #[inline]
362 pub fn intersect_sphere (&self, sphere : &Sphere3 <S>)
363 -> Option <((S, Point3 <S>), (S, Point3 <S>))>
364 where
365 S : Field + Sqrt
366 {
367 intersect::continuous_segment3_sphere3 (self, sphere)
368 }
369 #[inline]
370 pub fn intersect_cylinder (&self, sphere : &Cylinder3 <S>)
371 -> Option <((S, Point3 <S>), (S, Point3 <S>))>
372 where
373 S : Real + std::fmt::Debug
374 {
375 intersect::continuous_segment3_cylinder3 (self, sphere)
376 }
377 #[inline]
378 pub fn intersect_capsule (&self, capsule : &Capsule3 <S>)
379 -> Option <((S, Point3 <S>), (S, Point3 <S>))>
380 where
381 S : Real + std::fmt::Debug
382 {
383 intersect::continuous_segment3_capsule3 (self, capsule)
384 }
385 }
386 impl <S : Field> Default for Segment <S> {
387 fn default() -> Self {
398 Segment {
399 a: [-S::one(), S::zero(), S::zero()].into(),
400 b: [ S::one(), S::zero(), S::zero()].into()
401 }
402 }
403 }
404
405 impl <S : Ring> Triangle <S> {
406 pub fn new (
416 a : Point3 <S>,
417 b : Point3 <S>,
418 c : Point3 <S>
419 ) -> Self where
420 S : Field + Sqrt + approx::RelativeEq + std::fmt::Debug
421 {
422 debug_assert_ne!(a, b);
423 debug_assert_ne!(a, c);
424 debug_assert_ne!(b, c);
425 assert!(!colinear_3d (&a, &b, &c));
426 Triangle { a, b, c }
427 }
428 pub fn unchecked (
438 a : Point3 <S>,
439 b : Point3 <S>,
440 c : Point3 <S>
441 ) -> Self where
442 S : Field + Sqrt + approx::RelativeEq + std::fmt::Debug
443 {
444 debug_assert_ne!(a, b);
445 debug_assert_ne!(a, c);
446 debug_assert_ne!(b, c);
447 debug_assert!(!colinear_3d (&a, &b, &c));
448 Triangle { a, b, c }
449 }
450 #[inline]
451 pub fn point_a (&self) -> &Point3 <S> {
452 &self.a
453 }
454 #[inline]
455 pub fn point_b (&self) -> &Point3 <S> {
456 &self.b
457 }
458 #[inline]
459 pub fn point_c (&self) -> &Point3 <S> {
460 &self.c
461 }
462 }
463 impl <S : Field + Sqrt> Default for Triangle <S> {
464 fn default() -> Self {
491 let frac_1_sqrt_2 = S::one() / (S::one() + S::one()).sqrt();
492 Triangle {
493 a: [ S::zero(), S::one(), S::zero()].into(),
494 b: [-frac_1_sqrt_2, -frac_1_sqrt_2, S::zero()].into(),
495 c: [ frac_1_sqrt_2, -frac_1_sqrt_2, S::zero()].into()
496 }
497 }
498 }
499
500 impl <S : Ring> Tetrahedron <S> {
501 pub fn new (
512 a : Point3 <S>,
513 b : Point3 <S>,
514 c : Point3 <S>,
515 d : Point3 <S>
516 ) -> Self where
517 S : approx::RelativeEq
518 {
519 assert!(!coplanar_3d (&a, &b, &c, &d));
520 Tetrahedron { a, b, c, d }
521 }
522 pub fn unchecked (
533 a : Point3 <S>,
534 b : Point3 <S>,
535 c : Point3 <S>,
536 d : Point3 <S>
537 ) -> Self where
538 S : approx::RelativeEq
539 {
540 debug_assert!(!coplanar_3d (&a, &b, &c, &d));
541 Tetrahedron { a, b, c, d }
542 }
543 #[inline]
544 pub fn point_a (&self) -> &Point3 <S> {
545 &self.a
546 }
547 #[inline]
548 pub fn point_b (&self) -> &Point3 <S> {
549 &self.b
550 }
551 #[inline]
552 pub fn point_c (&self) -> &Point3 <S> {
553 &self.c
554 }
555 #[inline]
556 pub fn point_d (&self) -> &Point3 <S> {
557 &self.d
558 }
559 }
560 impl <S : Field + Sqrt> Default for Tetrahedron <S> {
561 fn default() -> Self {
592 let frac_1_3 = S::one() / S::three();
593 let sqrt_2_3 = (S::two() / S::three()).sqrt();
594 let sqrt_8_9 = (S::eight() / S::nine()).sqrt();
595 let sqrt_2_9 = (S::two() / S::nine()).sqrt();
596 Tetrahedron {
597 a: [S::zero(), S::zero(), S::one()].into(),
598 b: [S::zero(), sqrt_8_9, -frac_1_3].into(),
599 c: [ sqrt_2_3, -sqrt_2_9, -frac_1_3].into(),
600 d: [-sqrt_2_3, -sqrt_2_9, -frac_1_3].into()
601 }
602 }
603 }
604}