API Documentation
Loading...
Searching...
No Matches
Intersection.hpp
Go to the documentation of this file.
1/*--------------------------------------------------------------------------------------------
2Copyright (c) 2019, NDEVR LLC
3tyler.parke@ndevr.org
4 __ __ ____ _____ __ __ _______
5 | \ | | | __ \ | ___|\ \ / / | __ \
6 | \ | | | | \ \ | |___ \ \ / / | |__) |
7 | . \| | | |__/ / | |___ \ V / | _ /
8 | |\ |_|_____/__|_____|___\_/____| | \ \
9 |__| \__________________________________| \__\
10
11Subject to the terms of the Enterprise+ Agreement, NDEVR hereby grants
12Licensee a limited, non-exclusive, non-transferable, royalty-free license
13(without the right to sublicense) to use the API solely for the purpose of
14Licensee's internal development efforts to develop applications for which
15the API was provided.
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
23FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25DEALINGS IN THE SOFTWARE.
26
27Library: Base
28File: Intersection
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include <NDEVR/Triangle.h>
34#include <NDEVR/Bounds.h>
35#include <NDEVR/LineSegment.h>
36#include <NDEVR/Vector.h>
37#include <NDEVR/Polygon.h>
38#include <NDEVR/Plane.h>
39namespace NDEVR
40{
41 /**
42 \brief Dummy class for including intersection functions
43 **/
45 {};
46 constexpr fltp08 intersection_epsilon = 0.0001;
47 /**
48
49 \brief Given two bounds, returns the intersection between the two of them. If no intersection occurs,
50 the returned bounds will be invalid.
51
52 Author: Tyler Parke
53
54 Date: 2017-11-19
55
56 Parameters:
57 bounds_1 - The first bounds used for intersection
58 bounds_2 - The second bounds used for intersection
59
60 \returns A Bounds&lt;t_dims,t_type,t_vertex&gt; representing the intersection of the two inputs.
61 This value will be invalid if the bounds do not intersect.
62 **/
63 template<uint01 t_dims, class t_type, class t_vertex>
65 {
66 return Bounds<t_dims, t_type, t_vertex>(getMax(bounds_1[MIN], bounds_2[MIN]), getMin(bounds_1[MAX], bounds_2[MAX]));
67 }
68
69
70
71 /**
72
73 Intersections.
74
75 Author: Tyler Parke
76
77 Date: 2017-11-19
78
79 Parameters:
80 bounds - The bounds.
81 line - The line.
82
83 \returns A LineSegment&lt;t_dims,t_type&gt;
84
85 **/
86 template<uint01 t_dims, class t_type, class t_vertex>
87 static LineSegment<t_dims, t_type> intersection(const Bounds<t_dims, t_type, t_vertex>& bounds, const LineSegment<t_dims, t_type, t_vertex>& line)
88 {
89 LineSegment<t_dims, t_type> intersected_line = line;
90 for (uint01 dim = 0; dim < t_dims; ++dim)
91 {
92 if (intersected_line.vertex(A)[dim] < bounds[MIN][dim])
93 {
94 if (intersected_line.vertex(B)[dim] < bounds[MIN][dim])
95 return Constant<LineSegment<t_dims, t_type>>::Invalid;
96 else
97 intersected_line.vertex(A) = line.template pointAt<true>(bounds[MIN][dim], dim);
98 }
99 else if (intersected_line.vertex(B)[dim] < bounds[MIN][dim])
100 {
101 intersected_line.vertex(B) = line.template pointAt<true>(bounds[MIN][dim], dim);
102 }
103 if (intersected_line.vertex(A)[dim] > bounds[MAX][dim])
104 {
105 if (intersected_line.vertex(B)[dim] > bounds[MAX][dim])
106 return Constant<LineSegment<t_dims, t_type>>::Invalid;
107 else
108 intersected_line.vertex(A) = line.template pointAt<true>(bounds[MAX][dim], dim);
109 }
110 else if (intersected_line.vertex(B)[dim] > bounds[MAX][dim])
111 {
112 intersected_line.vertex(B) = line.template pointAt<true>(bounds[MAX][dim], dim);
113 }
114 }
115 return intersected_line;
116 }
117
118 /**
119
120 Intersections.
121
122 Author: Tyler Parke
123
124 Date: 2017-11-19
125
126 Parameters:
127 tri - The triangle.
128 line - The line.
129 epsilon - (Optional) The epsilon.
130
131 \returns A Vector&lt;t_dims,t_type&gt;
132
133 **/
134 template<uint01 t_dims, class t_type, class t_vertex>
135 static t_vertex intersection(const Triangle<t_dims, t_type, t_vertex>& tri, const LineSegment<t_dims, t_type, t_vertex>& line, t_type epsilon = 0)
136 {
137 const t_vertex tri_edge_ab(tri.edge(A, B).ray());
138 const t_vertex tri_edge_ca(tri.edge(A, C).ray());
139 const t_vertex line_ray(line.ray().template normalized<t_type>());
140 const t_vertex cross_line_tri = cross(line_ray, tri_edge_ca);
141 const t_type determinant = dot(tri_edge_ab, cross_line_tri);
142 if (abs(determinant) < epsilon)
144
145 const t_vertex t = line.vertex(A) - tri.vertex(A);
146 const t_type u0 = dot(t, cross_line_tri) / determinant;
147 if (u0 < cast<t_type>(0) || u0 > cast<t_type>(1))
149 const t_vertex q = cross(t, tri_edge_ab);
150 const t_type v = dot(line_ray, q) / determinant;
151 if (v < cast<t_type>(0) || u0 + v > cast<t_type>(1))
153 // At this stage we can compute t to find out where the intersection point is on the line.
154 const t_type final_t = dot(tri_edge_ca, q) / determinant;
155 if (final_t > epsilon && final_t * final_t < line.lengthSquared())
156 return final_t * line_ray + line.vertex(A);
157 else
158 return Constant<t_vertex>::Invalid;// This means that there is a line intersection but not a segment intersection.
159 }
160 /**
161
162 Given two triangles, returns the intersection between the two of them assuming that intesection is a line.
163 If no intersection occurs, the returned line will be Invalid. if intersection occurs at a point that point
164 will be returned. If the triangles are coplainer, Invalid is returned as this function is not designed to
165 intersect coplainer triangles.
166
167 Author: Tyler Parke
168
169 Date: 2017-11-19
170
171 Parameters:
172 tri_a - The triangle a.
173 tri_b - The triangle b.
174 epsilon - (Optional) The epsilon.
175
176 \returns A LineSegment&lt;t_dims,t_type,t_vertex&gt;
177
178 **/
179 template<uint01 t_dims, class t_type, class t_vertex>
180 static LineSegment<t_dims, t_type, t_vertex> intersection(const Triangle<t_dims, t_type, t_vertex>& tri_a, const Triangle<t_dims, t_type, t_vertex>& tri_b, t_type epsilon = 0)
181 {
182 UNUSED(epsilon);
183 const t_vertex normal_a = tri_a.template normal<true>();
184 const t_vertex normal_b = tri_b.template normal<true>();
185 if (normal_a == normal_b)
186 return Constant<LineSegment<t_dims, t_type, t_vertex>>::Invalid;//We fully intersect the plane, thus cannot produce a linesegment (edge case)
187 const t_type dot_1a = dot(normal_b, tri_a.vertex(A) - tri_b.vertex(A));
188 const t_type dot_1b = dot(normal_b, tri_a.vertex(B) - tri_b.vertex(A));
189 const t_type dot_1c = dot(normal_b, tri_a.vertex(C) - tri_b.vertex(A));
190 if ((dot_1a > 0 && dot_1b > 0 && dot_1c > 0) || (dot_1a < 0 && dot_1b < 0 && dot_1c < 0))
191 return Constant<LineSegment<t_dims, t_type, t_vertex>>::Invalid;
192
193 if (dot_1a == 0 || dot_1b == 0 || dot_1c == 0)
194 {
195 return Constant<LineSegment<t_dims, t_type, t_vertex>>::Invalid;
196 }
197 const t_type dot_2a = dot(normal_a, tri_b.vertex(A) - tri_a.vertex(A));
198 const t_type dot_2b = dot(normal_a, tri_b.vertex(B) - tri_a.vertex(A));
199 const t_type dot_2c = dot(normal_a, tri_b.vertex(C) - tri_a.vertex(A));
200
201 if ((dot_2a > 0 && dot_2b > 0 && dot_2c > 0) || (dot_2a < 0 && dot_2b < 0 && dot_2c < 0))
202 return Constant<LineSegment<t_dims, t_type, t_vertex>>::Invalid;//No intersection
203
204 if (dot_2a == 0 || dot_2b == 0 || dot_2c == 0)
205 return Constant<LineSegment<t_dims, t_type, t_vertex>>::Invalid;//We fully intersect the plane, thus cannot produce a linesegment (edge case)
206
207 const t_vertex seg_a1(tri_a.vertex(A) + (tri_a.vertex(B) - tri_a.vertex(A)) * (dot_1a / (dot_1a - dot_1b)));
208 const t_vertex seg_a2(tri_a.vertex(A) + (tri_a.vertex(C) - tri_a.vertex(A)) * (dot_1a / (dot_1a - dot_1c)));
209
210 const t_vertex seg_b1(tri_b.vertex(A) + (tri_b.vertex(B) - tri_b.vertex(A)) * (dot_2a / (dot_2a - dot_2b)));
211 const t_vertex seg_b2(tri_b.vertex(A) + (tri_b.vertex(C) - tri_b.vertex(A)) * (dot_2a / (dot_2a - dot_2c)));
212
213 const t_vertex cross_normal = cross(normal_a, normal_b).template normalized<t_type>();
214
215 const t_type tp13 = dot(seg_a2 - seg_a1, cross_normal);
216 const t_type Ip1 = getMin(cast<t_type>(0), tp13);
217 const t_type Ip2 = getMax(cast<t_type>(0), tp13);
218
219 const t_type tq12 = dot(seg_b1 - seg_a1, cross_normal);
220 const t_type tq13 = dot(seg_b2 - seg_a1, cross_normal);
221
222 const t_type Iq1 = getMin(tq12, tq13);
223 const t_type Iq2 = getMax(tq12, tq13);
224
225
226 if (abs(Ip1 - Iq1) * 2 < ((Ip2 - Ip1) + (Iq2 - Iq1)))
227 {
228 t_type n_b = getMax(Ip1, Iq1);
229 t_type n_a = getMin(Ip2, Iq2);
230 if (n_a > n_b)
231 {
232 return LineSegment<t_dims, t_type, t_vertex>(seg_a1 + cross_normal * n_a, seg_a1 + cross_normal * n_b);
233 }
234 }
235 return Constant<LineSegment<t_dims, t_type, t_vertex>>::Invalid;
236 }
237
238 /**
239
240 Given two triangles, returns the intersection between the two of them assuming that intesection is a line.
241 If no intersection occurs, the returned line will be Invalid. if intersection occurs at a point that point
242 will be returned. If the triangles are coplainer, Invalid is returned as this function is not designed to
243 intersect coplainer triangles.
244
245 Author: Tyler Parke
246
247 Date: 2017-11-19
248
249 Parameters:
250 tri_a - The triangle a.
251 tri_b - The triangle b.
252 epsilon - (Optional) The epsilon.
253
254 \returns A LineSegment&lt;t_dims,t_type,t_vertex&gt;
255 **/
256 template<uint01 t_dims, class t_type, class t_vertex>
257 static LineSegment<t_dims, t_type, t_vertex> intersection(const Triangle<t_dims, t_type, t_vertex>& tri_a, const Plane<t_dims, t_type>& plane, t_type epsilon = 0)
258 {
259 UNUSED(epsilon);
260 const t_type signed_dist_a = plane.distanceTo(tri_a.vertex(A));
261 const t_type signed_dist_b = plane.distanceTo(tri_a.vertex(B));
262 const t_type signed_dist_c = plane.distanceTo(tri_a.vertex(C));
263 LineSegment<t_dims, t_type, t_vertex> seg = Constant<LineSegment<t_dims, t_type, t_vertex>>::Invalid;
264 uint01 seg_location = 0;
265
266 if (signed_dist_a == 0.0)
267 {
268 if (signed_dist_b == 0.0)
269 {
270 if (signed_dist_c != 0.0)
271 {
272 seg[A] = tri_a.vertex(A);
273 seg[B] = tri_a.vertex(B);
274 }//else is on same plane so return Invalid
275 return seg;
276 }
277 else if (signed_dist_c == 0.0)
278 {
279 seg[A] = tri_a.vertex(A);
280 seg[B] = tri_a.vertex(C);
281 return seg;
282 }
283 else
284 {
285 seg[seg_location++] = tri_a.vertex(A);
286 }
287 }
288 if (signed_dist_b == 0.0)
289 {
290 if (signed_dist_c == 0.0)
291 {
292 seg[A] = tri_a.vertex(B);
293 seg[B] = tri_a.vertex(C);
294 return seg;
295 }
296 seg[seg_location++] = tri_a.vertex(B);
297 }
298 if (signed_dist_c == 0.0)
299 {
300 seg[seg_location++] = tri_a.vertex(C);
301 }
302 if (signed_dist_a * signed_dist_b < 0)
303 {
304 t_type t = signed_dist_a / (signed_dist_a - signed_dist_b); // 'time' of intersection point on the segment
305 seg[seg_location++] = tri_a.vertex(A) + t * (tri_a.vertex(B) - tri_a.vertex(A));
306 }
307 if (signed_dist_b * signed_dist_c < 0)
308 {
309 t_type t = signed_dist_b / (signed_dist_b - signed_dist_c); // 'time' of intersection point on the segment
310 seg[seg_location++] = tri_a.vertex(B) + t * (tri_a.vertex(C) - tri_a.vertex(B));
311 }
312 if (signed_dist_c * signed_dist_a < 0)
313 {
314 t_type t = signed_dist_c / (signed_dist_c - signed_dist_a); // 'time' of intersection point on the segment
315 seg[seg_location++] = tri_a.vertex(C) + t * (tri_a.vertex(A) - tri_a.vertex(C));
316 }
317 return seg;
318 }
319 template<uint01 t_dims, class t_type, class t_vertex>
320 static LineSegment<t_dims, t_type, t_vertex> intersection(const Plane<t_dims, t_type>& plane, const Triangle<t_dims, t_type, t_vertex>& tri_a, t_type epsilon = 0)
321 {
322 return intersection(tri_a, plane, epsilon);
323 }
324
325
326//////////////////////////////VERTEX CLASSIFY//////////////////////////////////////////////
327
328 template<uint01 t_dims, class t_type>
330 {
331 if (v1 == v2)
332 return mixed;
333 return outside;
334 }
335
336 template<uint01 t_dims, class t_type, class t_vertex>
338 {
339 if (tri.contains(point))
340 return mixed;
341 return outside;
342 }
343 /**
344
345 Classifies.
346
347 Author: Tyler Parke
348
349 Date: 2017-11-19
350
351 Parameters:
352 vertex - The vertex.
353 bounds - The bounds.
354
355 \returns The IntersectionTypes.
356 **/
357 template<uint01 t_dims, class t_type, class t_vertex>
358 IntersectionTypes classify(const t_vertex& vertex, const Bounds<t_dims, t_type, t_vertex>& bounds)
359 {
360 if (bounds.contains(vertex))
361 return mixed;
362 return outside;
363 }
364
365
366 /**
367
368 Classifies.
369
370 Author: Tyler Parke
371
372 Date: 2017-11-19
373
374 Parameters:
375 vector - The vector.
376 rad - The radians.
377
378 \returns The IntersectionTypes.
379 **/
380 template<uint01 t_dims, class t_type, class t_vertex>
382 {
383 if (rad.contains(vector))
384 return mixed;
385 return outside;
386 }
387
388 template<class t_type, class t_vertex>
389 IntersectionTypes classify(const t_vertex& vector, const Polygon<t_type, t_vertex>& polygon)
390 {
391 if (polygon.contains(vector))
392 return mixed;
393 return outside;
394 }
395//////////////////////////////LINE SEGMENT CLASSIFY//////////////////////////////////////////////
396
397 template<uint01 t_dims, class t_type, class t_vertex>
399 {
400 if(distanceSquared(line, vertex) < intersection_epsilon)
401 return inside;
402 return outside;
403 }
404
405
406 template<uint01 t_dims, class t_type, class t_vertex>
408 {
409 if (distanceSquared(left, right[A]) < intersection_epsilon)
410 {
411 if (distanceSquared(left, right[B]) < intersection_epsilon)
412 return inside;
413 else
414 return mixed;
415 }
416 if (distanceSquared(left, right) < intersection_epsilon)
417 return mixed;
418 return outside;
419 }
420 /**
421
422 Classifies.
423
424 Author: Tyler Parke
425
426 Date: 2017-11-19
427
428 Parameters:
429 line - The line.
430 tri - The triangle.
431
432 \returns The IntersectionTypes.
433 **/
434 template<uint01 t_dims, class t_type, class t_vertex>
436 {
437 t_type epsilon = cast<t_type>(0.0000001);
438 t_vertex edge_ba = tri.vertex(B) - tri.vertex(A);
439 t_vertex edge_ca = tri.vertex(C) - tri.vertex(A);
440 t_vertex dir = line.ray().template normalized<t_type>();
441 t_vertex pvec(cross(dir, edge_ca));
442 t_type det = dot(edge_ba, pvec);
443
444 // ray and triangle are parallel if det is close to 0
445 if (abs(det) < epsilon)
447 t_type invDet = cast<t_type>(1) / det;
448
449 t_vertex tvec = line.vertex(A) - tri.vertex(A);
450 t_type u = dot(tvec, pvec) * invDet;
451 if (u < cast<t_type>(0) || u > cast<t_type>(1))
453
454 t_vertex qvec(cross(tvec, edge_ba));
455 t_type v = dot(dir, qvec) * invDet;
456 if (v < cast<t_type>(0) || u + v > cast<t_type>(1))
458
459 t_type t = dot(edge_ca, qvec) * invDet;
460 if (t * t > line.lengthSquared())
463 }
464 /**
465
466 Classifies.
467
468 Author: Tyler Parke
469
470 Date: 2017-11-19
471
472 Parameters:
473 line - The line.
474 bounds - The bounds.
475
476 \returns The IntersectionTypes.
477 **/
478 template<uint01 t_dims, class t_type, class t_vertex>
483 template<uint01 t_dims, class t_type, class t_vertex>
485 {
486 return polygon.template contains<t_type>(line.template as<2, t_type>());
487 }
488
489////////////////////Plane Classify///////////////////////////////////////////////
490 template<uint01 t_dims, class t_type, class t_vertex>
491 IntersectionTypes classify(const Plane<t_dims, t_type>& plane, const t_vertex& point)
492 {
493 if (plane.contains(point, cast<t_type>(0.0001)))
494 return inside;
495 return outside;
496 }
497 template<uint01 t_dims, class t_type, class t_vertex>
498 IntersectionTypes classify(const t_vertex& point, const Plane<t_dims, t_type>& plane)
499 {
500 if (plane.contains(point, cast<t_type>(0.0001)))
501 return mixed;
502 return outside;
503 }
504 template<uint01 t_dims, class t_type, class t_vertex>
506 {
507 const PlanePosition position_a = plane.planePosition(line.vertex(A));
508 const PlanePosition position_b = plane.planePosition(line.vertex(B));
509 if (position_a == position_b)
510 {
511 if (position_a == PlanePosition::e_on_plane)
512 return inside;
513 else
514 return outside;
515 }
516 return mixed;
517 }
518 template<uint01 t_dims, class t_type, class t_vertex>
520 {
521 const PlanePosition position_a = plane.planePosition(line.vertex(A));
522 const PlanePosition position_b = plane.planePosition(line.vertex(B));
523 if (position_a == position_b)
524 {
525 if (position_a == PlanePosition::e_on_plane)
526 return mixed;
527 else
528 return outside;
529 }
530 return mixed;
531 }
532
533
534////////////////////TRIANGLE Classify///////////////////////////////////////////////
535 template<uint01 t_dims, class t_type, class t_vertex>
537 {
538 if (tri.contains(point))
539 return inside;
540 return outside;
541 }
542 /**
543
544 Classifies.
545
546 Author: Tyler Parke
547
548 Date: 2017-11-19
549
550 Parameters:
551 tri - The triangle.
552 line - The line.
553
554 \returns The IntersectionTypes.
555 **/
556 template<uint01 t_dims, class t_type, class t_vertex>
558 {
559 if (IsInvalid(intersection(tri, line, cast<t_type>(intersection_epsilon))))
560 return outside;
561 return mixed;
562 }
563
564 template<uint01 t_dims, class t_type, class t_vertex>
566 {
567 return polygon.template contains<t_type>(tri.template as<2, t_type>());
568 }
569 template<uint01 t_dims, class t_type, class t_vertex>
571 {
572 const PlanePosition position_a = plane.planePosition(triangle.vertex(A));
573 const PlanePosition position_b = plane.planePosition(triangle.vertex(B));
574 const PlanePosition position_c = plane.planePosition(triangle.vertex(C));
575 if (position_a == position_b && position_a == position_c)
576 {
577 if (position_a == PlanePosition::e_on_plane)
578 return mixed;
579 else
580 return outside;
581 }
582 return mixed;
583 }
584 template<uint01 t_dims, class t_type, class t_vertex>
586 {
587 const PlanePosition position_a = plane.planePosition(triangle.vertex(A));
588 const PlanePosition position_b = plane.planePosition(triangle.vertex(B));
589 const PlanePosition position_c = plane.planePosition(triangle.vertex(C));
590 if (position_a == position_b && position_a == position_c)
591 {
592 if (position_a == PlanePosition::e_on_plane)
593 return inside;
594 else
595 return outside;
596 }
597 return mixed;
598 }
599
600/////////////////////////BOUNDS CLASSIFY//////////////////////////////////
601
602 /**
603
604 Classifies.
605
606 Author: Tyler Parke
607
608 Date: 2017-11-19
609
610 Parameters:
611 bounds - The bounds.
612 vertex - The vertex.
613
614 \returns The IntersectionTypes.
615 **/
616 template<uint01 t_dims, class t_type, class t_vertex>
617 IntersectionTypes classify(const Bounds<t_dims, t_type, t_vertex>& bounds, const t_vertex& vertex)
618 {
619 if (bounds.contains(vertex))
620 return inside;
621 return outside;
622 }
623
624 /**
625
626 Classifies.
627
628 Author: Tyler Parke
629
630 Date: 2017-11-19
631
632 Parameters:
633 bounds - The bounds.
634 line - The line.
635
636 \returns The IntersectionTypes.
637 **/
638 template<uint01 t_dims, class t_type, class t_vertex>
640 {
641 if (bounds.contains(line))
642 {
643 return inside;
644 }
645 const Vertex<t_dims, t_type> ray = line.ray();
646 for (uint01 i = 0; i < t_dims; ++i)
647 {
648 if (bounds.doesIntersect(line.vertex(A)[i] - bounds[MIN][i], line.vertex(B)[i] - bounds[MIN][i], line.vertex(A), ray, i)
649 || bounds.doesIntersect(line.vertex(A)[i] - bounds[MAX][i], line.vertex(B)[i] - bounds[MAX][i], line.vertex(A), ray, i))
650 return mixed;
651 }
652 return outside;
653 }
654
655
656
657 /**
658
659 Classifies.
660
661 Author: Tyler Parke
662
663 Date: 2017-11-19
664
665 Parameters:
666 bounds - The bounds.
667 tri - The triangle.
668
669 \returns The IntersectionTypes.
670 **/
671 template<uint01 t_dims, class t_type, class t_vertex>
673 {
674 if (bounds.contains(tri))
675 return inside;
676 else
677 {
678 const t_vertex min = getMin(tri.vertex(A), tri.vertex(B), tri.vertex(C));
679 const t_vertex max = getMax(tri.vertex(A), tri.vertex(B), tri.vertex(C));
680 for (uint01 i = 0; i < t_dims; i++)
681 {
682 if (min[i] > bounds[MAX][i] || max[i] < bounds[MIN][i])
683 return outside;
684 }
685 }
686
687 const t_vertex bounds_center(bounds.center());
688 const Triangle<t_dims, t_type, t_vertex> centered_tri(
689 t_vertex(tri.vertex(A) - bounds_center)
690 , t_vertex(tri.vertex(B) - bounds_center)
691 , t_vertex(tri.vertex(C) - bounds_center));
692 const t_vertex half_span(bounds.span() / cast<t_type>(2));
693 const t_vertex edge[3] = { centered_tri.edge(A, B).ray(), centered_tri.edge(B, C).ray(), centered_tri.edge(C, A).ray() };
694 for (uint01 edge_index = 0; edge_index < 3; ++edge_index)
695 {
696 const t_vertex cur_edge = edge[edge_index];
697 const t_vertex abs_edge = abs(edge[edge_index]);
698 for (uint01 i = 0; i < 3; ++i)
699 {
700 t_type val_a;
701 t_type val_b;
702 t_type radius;
703 switch (i)
704 {
705 case 0:
706 val_a = cur_edge[Z] * centered_tri.vertex(A)[Y] - cur_edge[Y] * centered_tri.vertex(A)[Z];
707 val_b = cur_edge[Z] * centered_tri.vertex(C)[Y] - cur_edge[Y] * centered_tri.vertex(C)[Z];
708 radius = abs_edge[Z] * half_span[Y] + abs_edge[Y] * half_span[Z];
709 break;
710 case 1:
711 val_a = -cur_edge[Z] * centered_tri.vertex(A)[X] + cur_edge[X] * centered_tri.vertex(A)[Z];
712 val_b = -cur_edge[Z] * centered_tri.vertex(C)[X] + cur_edge[X] * centered_tri.vertex(C)[Z];
713 radius = abs_edge[Z] * half_span[X] + abs_edge[X] * half_span[Z];
714 break;
715 case 2:
716 default:
717 val_a = cur_edge[Y] * centered_tri.vertex(B)[X] - cur_edge[X] * centered_tri.vertex(B)[Y];
718 val_b = cur_edge[Y] * centered_tri.vertex(C)[X] - cur_edge[X] * centered_tri.vertex(C)[Y];
719 radius = abs_edge[Y] * half_span[X] + abs_edge[X] * half_span[Y];
720 break;
721 }
722 if (val_a < val_b)
723 {
724 if (val_a > radius || val_b < -radius)
725 return outside;
726 }
727 else
728 {
729 if (val_b > radius || val_a < -radius)
730 return outside;
731 }
732 }
733 }
734 const t_vertex normal = cross(edge[0], edge[1]);
735 t_vertex vertex_min;
736 t_vertex vertex_max;
737 for (uint01 i = 0; i < 3; i++)
738 {
739 t_type vertex_a_val = centered_tri.vertex(A)[i];
740 if (normal[i] > cast<t_type>(0))
741 {
742 vertex_min[i] = -half_span[i] - vertex_a_val;
743 vertex_max[i] = half_span[i] - vertex_a_val;
744 }
745 else
746 {
747 vertex_min[i] = half_span[i] - vertex_a_val;
748 vertex_max[i] = -half_span[i] - vertex_a_val;
749 }
750 }
751 if (dot(normal, vertex_min) > cast<t_type>(0) || dot(normal, vertex_max) < cast<t_type>(0))
752 return outside;
753 return mixed;
754 }
755
756 /**
757
758 Classifies.
759
760 Author: Tyler Parke
761
762 Date: 2017-11-19
763
764 Parameters:
765 outside - The outside.
766 inside - The inside.
767
768 \returns The IntersectionTypes.
769 **/
770 template<uint01 t_dims, class t_type, class t_vertex>
772 {
773 bool is_inside = true;
774 for (uint01 dim = 0; dim < t_dims; ++dim)
775 {
776 if (!(right[MIN][dim] >= left[MIN][dim]))
777 {
778 if (!(right[MAX][dim] >= left[MIN][dim]))
779 return outside;
780 is_inside = false;
781 }
782 if (!(right[MAX][dim] <= left[MAX][dim]))
783 {
784 if (!(right[MIN][dim] <= left[MAX][dim]))
785 return outside;
786 is_inside = false;
787 }
788 }
789 if (is_inside)
790 return inside;
791 return mixed;
792 }
793
794 /**
795
796 Classifies.
797
798 Author: Tyler Parke
799
800 Date: 2017-11-19
801
802 Parameters:
803 bounds - The bounds.
804 radial - The radial.
805
806 \returns The IntersectionTypes.
807 **/
808 template<uint01 t_dims, class t_type, class t_vertex>
810 {
811 const t_vertex center = radial.center();
812
813 uint01 inside_dims = 0;
814 t_type sqr_dist = cast<t_type>(0);
815
816 for (uint01 dim = 0; dim < t_dims; ++dim)
817 {
818 if (center[dim] < bounds[MIN][dim])
819 sqr_dist += (bounds[MIN][dim] - center[dim]) * (bounds[MIN][dim] - center[dim]);
820 else if (center[dim] > bounds[MAX][dim])
821 sqr_dist += (center[dim] - bounds[MAX][dim]) * (center[dim] - bounds[MAX][dim]);
822 else if (center[dim] >= bounds[MIN] + radial.radius() && center[dim] <= bounds[MAX][dim] - radial.radius())
823 inside_dims++;
824 }
825 if (inside_dims == t_dims)
826 return inside;
827 if (sqr_dist > radial.radius() * radial.radius())
828 return outside;
829 return mixed;
830 }
831
832
833
834 template<uint01 t_dims, class t_type, class t_vertex>
836 {
837 return polygon.template contains<t_type>(bounds.template as<2, t_type>());
838 }
839
840
841 template<uint01 t_dims, class t_type, class t_vertex>
843 {
844 t_vertex c = bounds.center(); // Compute AABB center
845 t_vertex e = bounds[MAX] - c; // Compute positive extents
846
847 // Compute the projection interval radius of b onto L(t) = b.c + t * p.n
848 t_type r = (e * abs(plane.normal)).sum();
849
850 // Compute distance of box center from plane
851 t_type s = dot(plane.normal, c) - plane.d;
852
853 // Intersection occurs when distance s falls within [-r,+r] interval
854 if (abs(s) <= r)
856 else
858 }
859
860 template<uint01 t_dims, class t_type, class t_vertex>
862 {
863 return classify(bounds, plane);
864 }
865
866/////////////////////////RADIAL OBJECT CLASSIFY/////////////////////////////////////
867 /**
868
869 Classifies.
870
871 Author: Tyler Parke
872
873 Date: 2017-11-19
874
875 Parameters:
876 rad - The radians.
877 vector - The vector.
878
879 \returns The IntersectionTypes.
880 **/
881 template<uint01 t_dims, class t_type, class t_vertex>
883 {
884 if (rad.contains(vector))
885 return inside;
886 return outside;
887 }
888 /**
889
890 Classifies.
891
892 Author: Tyler Parke
893
894 Date: 2017-11-19
895
896 Parameters:
897 radial - The radial.
898 bounds - The bounds.
899
900 \returns The IntersectionTypes.
901 **/
902 template<uint01 t_dims, class t_type, class t_vertex>
904 {
905 t_type max_tot(0);
906 t_type min_tot(0);
907 for (uint01 i = 0; i < t_dims; i++)
908 {
909 const t_type cir_center = radial.center()[i];
910 const t_type dist_max = (bounds[MAX][i] - cir_center) * (bounds[MAX][i] - cir_center);
911 const t_type dist_min = (bounds[MIN][i] - cir_center) * (bounds[MIN][i] - cir_center);
912 if (dist_max > dist_min)
913 {
914 max_tot += dist_max;
915 if (cir_center < bounds[MIN][i])
916 min_tot += dist_min;
917 }
918 else
919 {
920 max_tot += dist_min;
921 if (cir_center > bounds[MAX][i])
922 min_tot += dist_max;
923 }
924 }
925 const t_type rad_squared = radial.radius() * radial.radius();
926 if (max_tot < rad_squared)
927 return inside;
928 if (min_tot < rad_squared)
929 return mixed;
930 return outside;
931 }
932 template<uint01 t_dims, class t_type, class t_vertex>
934 {
935 t_vertex c = radial.center(); // Compute AABB
936 if (radial.radius() >= plane.distanceTo(c))
937 return mixed;
938 else
939 return outside;
940 }
941 template<uint01 t_dims, class t_type, class t_vertex>
943 {
944 return classify(radial, plane);
945 }
946
947 template<class t_type, class t_vertex>
948 IntersectionTypes classify(const Polygon<t_type, t_vertex>& polygon, const t_vertex& vector)
949 {
950 if (polygon.contains(vector))
951 return inside;
952 return outside;
953 }
954
955
956 template<uint01 t_dims, class t_type, class t_vertex>
958 {
959 return polygon.template contains<t_type>(bounds.template as<2, t_type>());
960 }
961
962
963 template<uint01 t_dims, class t_type, class t_vertex>
965 {
966 return polygon.template contains<t_type>(tri.template as<2, t_type>());
967 }
968
969
970 template<uint01 t_dims, class t_type, class t_vertex>
972 {
973 return polygon.template contains<t_type>(line.template as<2, t_type>());
974 }
975
976
977
978}
979
#define UNUSED(expr)
Definition BaseValues.hpp:409
A specification of upper and lower bounds in N-dimensions.
Definition Bounds.hpp:52
constexpr Ray< t_dims, t_type > span() const
The side lengths of these bounds. For each dimension, the span is max - min.
Definition Bounds.hpp:111
constexpr bool contains(const t_type &value) const
Query if this object contains the given value. t_allow_bounds - whether or not to allow boundary case...
Definition Bounds.hpp:237
constexpr t_vertex center() const
Returns the center of the bounds.
Definition Bounds.hpp:120
constexpr bool doesIntersect(t_type distance_a, t_type distance_b, const t_vertex &origin, const Vector< t_dims, t_type > &ray, uint01 exclusion_axis) const
Checks for intersection of the ray from a given distance, excluding one axis.
Definition Bounds.hpp:577
Dummy class for including intersection functions.
Definition Intersection.hpp:45
A line segment represented by two vertices, a start and end.
Definition Line.hpp:49
constexpr t_vertex ray() const
Definition Line.hpp:120
constexpr const t_vertex & vertex(uint01 index) const
Definition Line.hpp:152
constexpr t_type lengthSquared() const
Definition Line.hpp:463
Logic for a given plane or N-dimensions. Planes are coordinate systems of one less dimension than the...
Definition Geometry.h:41
t_type d
Definition Plane.hpp:223
t_type distanceTo(const Vector< t_dims, t_type > &pos) const
Definition Plane.hpp:110
PlanePosition planePosition(const Vector< t_dims, t_type > &pos) const
Definition Plane.hpp:88
Ray< t_dims, t_type > normal
Definition Plane.hpp:222
bool contains(const Vector< 3, t_type > &point, t_type epsilon) const
Definition Plane.hpp:202
An N-sided polygon.
Definition Polygon.hpp:53
bool contains(const Vertex< 2, t_type > &vector) const
Definition Polygon.hpp:478
A radial object.
Definition RadialObject.hpp:52
constexpr t_type radius() const
Definition RadialObject.hpp:123
constexpr const t_vertex & center() const
Definition RadialObject.hpp:152
constexpr bool contains(const t_vertex &vector) const
Definition RadialObject.hpp:105
A triangle is a polygon with three edges and three vertices. It is one of the basic shapes in geometr...
Definition Triangle.hpp:138
constexpr bool contains(const Vector< t_dims - 1, t_type > &p) const
Definition Triangle.hpp:443
constexpr t_vertex & vertex(TriangleLocation triangle_node)
Vertices the given triangle node.
Definition Triangle.hpp:168
constexpr LineSegment< t_dims, t_type, t_vertex > edge(uint01 triangle_node_a, uint01 triangle_node_b) const
Definition Triangle.hpp:256
A fixed-size array with better performance compared to dynamic containers.
Definition Vector.hpp:60
A vertex or point. A specific type of Vector used primarily for spacial location information.
Definition Vertex.hpp:48
Definition ACIColor.h:37
constexpr bool IsInvalid(const t_type &value)
Query if 'value' is valid or invalid. Invalid values should return invalid if used for calculations o...
Definition BaseFunctions.hpp:170
constexpr t_type getMax(const t_type &left, const t_type &right)
Finds the max of the given arguments using the > operator The only requirement is that t_type have > ...
Definition BaseFunctions.hpp:94
t_type dot(const Vector< t_dims, t_type > &v1, const Vector< t_dims, t_type > &v2)
Definition VectorFunctions.hpp:1030
@ MIN
Definition BaseValues.hpp:196
@ MAX
Definition BaseValues.hpp:197
@ edge_ca
Definition Triangle.hpp:51
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:80
t_type distanceSquared(const Bounds< t_dims, t_type, t_vertex > &bounds, const Vector< t_dims, t_type > &vertex)
Definition Distance.hpp:46
IntersectionTypes
Used for classifying shape intersections.
Definition BaseValues.hpp:210
@ inside
Definition BaseValues.hpp:212
@ mixed
Definition BaseValues.hpp:213
@ outside
Definition BaseValues.hpp:211
constexpr fltp08 intersection_epsilon
Definition Intersection.hpp:46
PlanePosition
The location of an object either below, above, or on a given N-dimensional plane.
Definition Plane.hpp:42
constexpr Vector< 1, t_type > cross(const Vector< 1, t_type > &, const Vector< 1, t_type > &)
Definition VectorFunctions.hpp:898
IntersectionTypes classify(const Vector< t_dims, t_type > &v1, const Vector< t_dims, t_type > &v2)
Definition Intersection.hpp:329
constexpr t_to cast(const Angle< t_from > &value)
Definition Angle.h:375
constexpr Angle< t_angle_type > abs(const Angle< t_angle_type > &value)
Changes an input with a negative sign, to a positive sign.
Definition AngleFunctions.h:645
@ B
Definition BaseValues.hpp:170
@ A
Definition BaseValues.hpp:168
@ Y
Definition BaseValues.hpp:169
@ X
Definition BaseValues.hpp:167
@ C
Definition BaseValues.hpp:172
@ Z
Definition BaseValues.hpp:171
double fltp08
Defines an alias representing an 8 byte floating-point number.
Definition BaseValues.hpp:149
constexpr t_type getMin(const t_type &left, const t_type &right)
Finds the minimum of the given arguments based on the < operator Author: Tyler Parke Date: 2017-11-05...
Definition BaseFunctions.hpp:56
static const t_type Invalid
Definition BaseValues.hpp:234