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>
39/**--------------------------------------------------------------------------------------------------
40Namespace: Parke
41Namespace that wraps all Logic created by Tyler Parke
42 *-----------------------------------------------------------------------------------------------**/
43
44namespace NDEVR
45{
47 {};
48 constexpr fltp08 intersection_epsilon = 0.0001;
49 /**--------------------------------------------------------------------------------------------------
50 Fn: static Bounds<t_dims, t_type, t_vertex> intersection(const Bounds<t_dims, t_type, t_vertex>& bounds_1,
51 const Bounds<t_dims, t_type, t_vertex>& bounds_2)
52
53 Given two bounds, returns the intersection between the two of them. If no intersection occurs,
54 the returned bounds will be invalid.
55
56 Author: Tyler Parke
57
58 Date: 2017-11-19
59
60 Parameters:
61 bounds_1 - The first bounds used for intersection
62 bounds_2 - The second bounds used for intersection
63
64 Returns: A Bounds&lt;t_dims,t_type,t_vertex&gt; representing the intersection of the two inputs.
65 This value will be invalid if the bounds do not intersect.
66 *-----------------------------------------------------------------------------------------------**/
67 template<uint01 t_dims, class t_type, class t_vertex>
69 {
70 return Bounds<t_dims, t_type, t_vertex>(getMax(bounds_1[MIN], bounds_2[MIN]), getMin(bounds_1[MAX], bounds_2[MAX]));
71 }
72
73
74
75 /**--------------------------------------------------------------------------------------------------
76 Fn: static LineSegment<t_dims, t_type> intersection(const Bounds<t_dims, t_type, t_vertex>& bounds,
77 const LineSegment<t_dims, t_type, t_vertex>& line)
78
79 Intersections.
80
81 Author: Tyler Parke
82
83 Date: 2017-11-19
84
85 Parameters:
86 bounds - The bounds.
87 line - The line.
88
89 Returns: A LineSegment&lt;t_dims,t_type&gt;
90 *-----------------------------------------------------------------------------------------------**/
91 template<uint01 t_dims, class t_type, class t_vertex>
92 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)
93 {
94 LineSegment<t_dims, t_type> intersected_line = line;
95 for (uint01 dim = 0; dim < t_dims; ++dim)
96 {
97 if (intersected_line.vertex(A)[dim] < bounds[MIN][dim])
98 {
99 if (intersected_line.vertex(B)[dim] < bounds[MIN][dim])
100 return Constant<LineSegment<t_dims, t_type>>::NaN;
101 else
102 intersected_line.vertex(A) = line.template pointAt<true>(bounds[MIN][dim], dim);
103 }
104 else if (intersected_line.vertex(B)[dim] < bounds[MIN][dim])
105 {
106 intersected_line.vertex(B) = line.template pointAt<true>(bounds[MIN][dim], dim);
107 }
108 if (intersected_line.vertex(A)[dim] > bounds[MAX][dim])
109 {
110 if (intersected_line.vertex(B)[dim] > bounds[MAX][dim])
111 return Constant<LineSegment<t_dims, t_type>>::NaN;
112 else
113 intersected_line.vertex(A) = line.template pointAt<true>(bounds[MAX][dim], dim);
114 }
115 else if (intersected_line.vertex(B)[dim] > bounds[MAX][dim])
116 {
117 intersected_line.vertex(B) = line.template pointAt<true>(bounds[MAX][dim], dim);
118 }
119 }
120 return intersected_line;
121 }
122
123 /**--------------------------------------------------------------------------------------------------
124 Fn: static Vector<t_dims, t_type> intersection(const Triangle<t_dims, t_type>& tri,
125 const LineSegment<t_dims, t_type>& line, t_type epsilon = 0)
126
127 Intersections.
128
129 Author: Tyler Parke
130
131 Date: 2017-11-19
132
133 Parameters:
134 tri - The triangle.
135 line - The line.
136 epsilon - (Optional) The epsilon.
137
138 Returns: A Vector&lt;t_dims,t_type&gt;
139 *-----------------------------------------------------------------------------------------------**/
140 template<uint01 t_dims, class t_type, class t_vertex>
141 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)
142 {
143 const t_vertex tri_edge_ab(tri.edge(A, B).ray());
144 const t_vertex tri_edge_ca(tri.edge(A, C).ray());
145 const t_vertex line_ray(line.ray().template normalized<t_type>());
146 const t_vertex cross_line_tri = cross(line_ray, tri_edge_ca);
147 const t_type determinant = dot(tri_edge_ab, cross_line_tri);
148 if (abs(determinant) < epsilon)
150
151 const t_vertex t = line.vertex(A) - tri.vertex(A);
152 const t_type u0 = dot(t, cross_line_tri) / determinant;
153 if (u0 < cast<t_type>(0) || u0 > cast<t_type>(1))
155 const t_vertex q = cross(t, tri_edge_ab);
156 const t_type v = dot(line_ray, q) / determinant;
157 if (v < cast<t_type>(0) || u0 + v > cast<t_type>(1))
159 // At this stage we can compute t to find out where the intersection point is on the line.
160 const t_type final_t = dot(tri_edge_ca, q) / determinant;
161 if (final_t > epsilon && final_t * final_t < line.lengthSquared())
162 return final_t * line_ray + line.vertex(A);
163 else
164 return Constant<t_vertex>::NaN;// This means that there is a line intersection but not a segment intersection.
165 }
166 /**--------------------------------------------------------------------------------------------------
167 Fn: static LineSegment<t_dims, t_type, t_vertex> intersection(const Triangle<t_dims, t_type, t_vertex>& tri_a,
168 const Triangle<t_dims, t_type, t_vertex>& tri_b, t_type epsilon = 0)
169
170 Given two triangles, returns the intersection between the two of them assuming that intesection is a line.
171 If no intersection occurs, the returned line will be NaN. if intersection occurs at a point that point
172 will be returned. If the triangles are coplainer, NaN is returned as this function is not designed to
173 intersect coplainer triangles.
174
175 Author: Tyler Parke
176
177 Date: 2017-11-19
178
179 Parameters:
180 tri_a - The triangle a.
181 tri_b - The triangle b.
182 epsilon - (Optional) The epsilon.
183
184 Returns: A LineSegment&lt;t_dims,t_type,t_vertex&gt;
185 *-----------------------------------------------------------------------------------------------**/
186 template<uint01 t_dims, class t_type, class t_vertex>
187 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)
188 {
189 UNUSED(epsilon);
190 const t_vertex normal_a = tri_a.template normal<true>();
191 const t_vertex normal_b = tri_b.template normal<true>();
192 if (normal_a == normal_b)
193 return Constant<LineSegment<t_dims, t_type, t_vertex>>::NaN;//We fully intersect the plane, thus cannot produce a linesegment (edge case)
194 const t_type dot_1a = dot(normal_b, tri_a.vertex(A) - tri_b.vertex(A));
195 const t_type dot_1b = dot(normal_b, tri_a.vertex(B) - tri_b.vertex(A));
196 const t_type dot_1c = dot(normal_b, tri_a.vertex(C) - tri_b.vertex(A));
197 if ((dot_1a > 0 && dot_1b > 0 && dot_1c > 0) || (dot_1a < 0 && dot_1b < 0 && dot_1c < 0))
198 return Constant<LineSegment<t_dims, t_type, t_vertex>>::NaN;
199
200 if (dot_1a == 0 || dot_1b == 0 || dot_1c == 0)
201 {
202 return Constant<LineSegment<t_dims, t_type, t_vertex>>::NaN;
203 }
204 const t_type dot_2a = dot(normal_a, tri_b.vertex(A) - tri_a.vertex(A));
205 const t_type dot_2b = dot(normal_a, tri_b.vertex(B) - tri_a.vertex(A));
206 const t_type dot_2c = dot(normal_a, tri_b.vertex(C) - tri_a.vertex(A));
207
208 if ((dot_2a > 0 && dot_2b > 0 && dot_2c > 0) || (dot_2a < 0 && dot_2b < 0 && dot_2c < 0))
209 return Constant<LineSegment<t_dims, t_type, t_vertex>>::NaN;//No intersection
210
211 if (dot_2a == 0 || dot_2b == 0 || dot_2c == 0)
212 return Constant<LineSegment<t_dims, t_type, t_vertex>>::NaN;//We fully intersect the plane, thus cannot produce a linesegment (edge case)
213
214 const t_vertex seg_a1(tri_a.vertex(A) + (tri_a.vertex(B) - tri_a.vertex(A)) * (dot_1a / (dot_1a - dot_1b)));
215 const t_vertex seg_a2(tri_a.vertex(A) + (tri_a.vertex(C) - tri_a.vertex(A)) * (dot_1a / (dot_1a - dot_1c)));
216
217 const t_vertex seg_b1(tri_b.vertex(A) + (tri_b.vertex(B) - tri_b.vertex(A)) * (dot_2a / (dot_2a - dot_2b)));
218 const t_vertex seg_b2(tri_b.vertex(A) + (tri_b.vertex(C) - tri_b.vertex(A)) * (dot_2a / (dot_2a - dot_2c)));
219
220 const t_vertex cross_normal = cross(normal_a, normal_b).template normalized<t_type>();
221
222 const t_type tp13 = dot(seg_a2 - seg_a1, cross_normal);
223 const t_type Ip1 = getMin(cast<t_type>(0), tp13);
224 const t_type Ip2 = getMax(cast<t_type>(0), tp13);
225
226 const t_type tq12 = dot(seg_b1 - seg_a1, cross_normal);
227 const t_type tq13 = dot(seg_b2 - seg_a1, cross_normal);
228
229 const t_type Iq1 = getMin(tq12, tq13);
230 const t_type Iq2 = getMax(tq12, tq13);
231
232
233 if (abs(Ip1 - Iq1) * 2 < ((Ip2 - Ip1) + (Iq2 - Iq1)))
234 {
235 t_type n_b = getMax(Ip1, Iq1);
236 t_type n_a = getMin(Ip2, Iq2);
237 if (n_a > n_b)
238 {
239 return LineSegment<t_dims, t_type, t_vertex>(seg_a1 + cross_normal * n_a, seg_a1 + cross_normal * n_b);
240 }
241 }
242 return Constant<LineSegment<t_dims, t_type, t_vertex>>::NaN;
243 }
244
245 /**--------------------------------------------------------------------------------------------------
246 Fn: static LineSegment<t_dims, t_type, t_vertex> intersection(const Triangle<t_dims, t_type, t_vertex>& tri_a,
247 const Triangle<t_dims, t_type, t_vertex>& tri_b, t_type epsilon = 0)
248
249 Given two triangles, returns the intersection between the two of them assuming that intesection is a line.
250 If no intersection occurs, the returned line will be NaN. if intersection occurs at a point that point
251 will be returned. If the triangles are coplainer, NaN is returned as this function is not designed to
252 intersect coplainer triangles.
253
254 Author: Tyler Parke
255
256 Date: 2017-11-19
257
258 Parameters:
259 tri_a - The triangle a.
260 tri_b - The triangle b.
261 epsilon - (Optional) The epsilon.
262
263 Returns: A LineSegment&lt;t_dims,t_type,t_vertex&gt;
264 *-----------------------------------------------------------------------------------------------**/
265 template<uint01 t_dims, class t_type, class t_vertex>
266 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)
267 {
268 UNUSED(epsilon);
269 const t_type signed_dist_a = plane.distanceTo(tri_a.vertex(A));
270 const t_type signed_dist_b = plane.distanceTo(tri_a.vertex(B));
271 const t_type signed_dist_c = plane.distanceTo(tri_a.vertex(C));
272 LineSegment<t_dims, t_type, t_vertex> seg = Constant<LineSegment<t_dims, t_type, t_vertex>>::NaN;
273 uint01 seg_location = 0;
274
275 if (signed_dist_a == 0.0)
276 {
277 if (signed_dist_b == 0.0)
278 {
279 if (signed_dist_c != 0.0)
280 {
281 seg[A] = tri_a.vertex(A);
282 seg[B] = tri_a.vertex(B);
283 }//else is on same plane so return NaN
284 return seg;
285 }
286 else if (signed_dist_c == 0.0)
287 {
288 seg[A] = tri_a.vertex(A);
289 seg[B] = tri_a.vertex(C);
290 return seg;
291 }
292 else
293 {
294 seg[seg_location++] = tri_a.vertex(A);
295 }
296 }
297 if (signed_dist_b == 0.0)
298 {
299 if (signed_dist_c == 0.0)
300 {
301 seg[A] = tri_a.vertex(B);
302 seg[B] = tri_a.vertex(C);
303 return seg;
304 }
305 seg[seg_location++] = tri_a.vertex(B);
306 }
307 if (signed_dist_c == 0.0)
308 {
309 seg[seg_location++] = tri_a.vertex(C);
310 }
311 if (signed_dist_a * signed_dist_b < 0)
312 {
313 t_type t = signed_dist_a / (signed_dist_a - signed_dist_b); // 'time' of intersection point on the segment
314 seg[seg_location++] = tri_a.vertex(A) + t * (tri_a.vertex(B) - tri_a.vertex(A));
315 }
316 if (signed_dist_b * signed_dist_c < 0)
317 {
318 t_type t = signed_dist_b / (signed_dist_b - signed_dist_c); // 'time' of intersection point on the segment
319 seg[seg_location++] = tri_a.vertex(B) + t * (tri_a.vertex(C) - tri_a.vertex(B));
320 }
321 if (signed_dist_c * signed_dist_a < 0)
322 {
323 t_type t = signed_dist_c / (signed_dist_c - signed_dist_a); // 'time' of intersection point on the segment
324 seg[seg_location++] = tri_a.vertex(C) + t * (tri_a.vertex(A) - tri_a.vertex(C));
325 }
326 return seg;
327 }
328 template<uint01 t_dims, class t_type, class t_vertex>
329 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)
330 {
331 return intersection(tri_a, plane, epsilon);
332 }
333
334
335//////////////////////////////VERTEX CLASSIFY//////////////////////////////////////////////
336
337 template<uint01 t_dims, class t_type>
339 {
340 if (v1 == v2)
341 return mixed;
342 return outside;
343 }
344
345 template<uint01 t_dims, class t_type, class t_vertex>
347 {
348 if (tri.contains(point))
349 return mixed;
350 return outside;
351 }
352 /**--------------------------------------------------------------------------------------------------
353 Fn: IntersectionTypes classify(const t_vertex& vertex,
354 const Bounds<t_dims, t_type, t_vertex>& bounds)
355
356 Classifies.
357
358 Author: Tyler Parke
359
360 Date: 2017-11-19
361
362 Parameters:
363 vertex - The vertex.
364 bounds - The bounds.
365
366 Returns: The IntersectionTypes.
367 *-----------------------------------------------------------------------------------------------**/
368 template<uint01 t_dims, class t_type, class t_vertex>
369 IntersectionTypes classify(const t_vertex& vertex, const Bounds<t_dims, t_type, t_vertex>& bounds)
370 {
371 if (bounds.contains(vertex))
372 return mixed;
373 return outside;
374 }
375
376
377 /**--------------------------------------------------------------------------------------------------
378 Fn: IntersectionTypes classify(const t_vertex& vector,
379 const RadialObject<t_dims, t_type, t_vertex>& rad)
380
381 Classifies.
382
383 Author: Tyler Parke
384
385 Date: 2017-11-19
386
387 Parameters:
388 vector - The vector.
389 rad - The radians.
390
391 Returns: The IntersectionTypes.
392 *-----------------------------------------------------------------------------------------------**/
393 template<uint01 t_dims, class t_type, class t_vertex>
395 {
396 if (rad.contains(vector))
397 return mixed;
398 return outside;
399 }
400
401 template<class t_type, class t_vertex>
402 IntersectionTypes classify(const t_vertex& vector, const Polygon<t_type, t_vertex>& polygon)
403 {
404 if (polygon.contains(vector))
405 return mixed;
406 return outside;
407 }
408//////////////////////////////LINE SEGMENT CLASSIFY//////////////////////////////////////////////
409
410 template<uint01 t_dims, class t_type, class t_vertex>
412 {
413 if(distanceSquared(line, vertex) < intersection_epsilon)
414 return inside;
415 return outside;
416 }
417
418
419 template<uint01 t_dims, class t_type, class t_vertex>
421 {
422 if (distanceSquared(left, right[A]) < intersection_epsilon)
423 {
424 if (distanceSquared(left, right[B]) < intersection_epsilon)
425 return inside;
426 else
427 return mixed;
428 }
429 if (distanceSquared(left, right) < intersection_epsilon)
430 return mixed;
431 return outside;
432 }
433 /**--------------------------------------------------------------------------------------------------
434 Fn: IntersectionTypes classify(const LineSegment<t_dims, t_type, t_vertex>& line,
435 const Triangle<t_dims, t_type, t_vertex>& tri)
436
437 Classifies.
438
439 Author: Tyler Parke
440
441 Date: 2017-11-19
442
443 Parameters:
444 line - The line.
445 tri - The triangle.
446
447 Returns: The IntersectionTypes.
448 *-----------------------------------------------------------------------------------------------**/
449 template<uint01 t_dims, class t_type, class t_vertex>
451 {
452 t_type epsilon = cast<t_type>(0.0000001);
453 t_vertex edge_ba = tri.vertex(B) - tri.vertex(A);
454 t_vertex edge_ca = tri.vertex(C) - tri.vertex(A);
455 t_vertex dir = line.ray().template normalized<t_type>();
456 t_vertex pvec(cross(dir, edge_ca));
457 t_type det = dot(edge_ba, pvec);
458
459 // ray and triangle are parallel if det is close to 0
460 if (abs(det) < epsilon)
462 t_type invDet = cast<t_type>(1) / det;
463
464 t_vertex tvec = line.vertex(A) - tri.vertex(A);
465 t_type u = dot(tvec, pvec) * invDet;
466 if (u < cast<t_type>(0) || u > cast<t_type>(1))
468
469 t_vertex qvec(cross(tvec, edge_ba));
470 t_type v = dot(dir, qvec) * invDet;
471 if (v < cast<t_type>(0) || u + v > cast<t_type>(1))
473
474 t_type t = dot(edge_ca, qvec) * invDet;
475 if (t * t > line.lengthSquared())
478 }
479 /**--------------------------------------------------------------------------------------------------
480 Fn: IntersectionTypes classify(const LineSegment<t_dims, t_type, t_vertex>& line,
481 const Bounds<t_dims, t_type, t_vertex>& bounds)
482
483 Classifies.
484
485 Author: Tyler Parke
486
487 Date: 2017-11-19
488
489 Parameters:
490 line - The line.
491 bounds - The bounds.
492
493 Returns: The IntersectionTypes.
494 *-----------------------------------------------------------------------------------------------**/
495 template<uint01 t_dims, class t_type, class t_vertex>
500 template<uint01 t_dims, class t_type, class t_vertex>
502 {
503 return polygon.template contains<t_type>(line.template as<2, t_type>());
504 }
505
506////////////////////Plane Classify///////////////////////////////////////////////
507 template<uint01 t_dims, class t_type, class t_vertex>
508 IntersectionTypes classify(const Plane<t_dims, t_type>& plane, const t_vertex& point)
509 {
510 if (plane.contains(point, cast<t_type>(0.0001)))
511 return inside;
512 return outside;
513 }
514 template<uint01 t_dims, class t_type, class t_vertex>
515 IntersectionTypes classify(const t_vertex& point, const Plane<t_dims, t_type>& plane)
516 {
517 if (plane.contains(point, cast<t_type>(0.0001)))
518 return mixed;
519 return outside;
520 }
521 template<uint01 t_dims, class t_type, class t_vertex>
523 {
524 const PlanePosition position_a = plane.planePosition(line.vertex(A));
525 const PlanePosition position_b = plane.planePosition(line.vertex(B));
526 if (position_a == position_b)
527 {
528 if (position_a == PlanePosition::e_on_plane)
529 return inside;
530 else
531 return outside;
532 }
533 return mixed;
534 }
535 template<uint01 t_dims, class t_type, class t_vertex>
537 {
538 const PlanePosition position_a = plane.planePosition(line.vertex(A));
539 const PlanePosition position_b = plane.planePosition(line.vertex(B));
540 if (position_a == position_b)
541 {
542 if (position_a == PlanePosition::e_on_plane)
543 return mixed;
544 else
545 return outside;
546 }
547 return mixed;
548 }
549
550
551////////////////////TRIANGLE Classify///////////////////////////////////////////////
552 template<uint01 t_dims, class t_type, class t_vertex>
554 {
555 if (tri.contains(point))
556 return inside;
557 return outside;
558 }
559 /**--------------------------------------------------------------------------------------------------
560 Fn: IntersectionTypes classify(const Triangle<t_dims, t_type, t_vertex>& tri,
561 const LineSegment<t_dims, t_type, t_vertex>& line)
562
563 Classifies.
564
565 Author: Tyler Parke
566
567 Date: 2017-11-19
568
569 Parameters:
570 tri - The triangle.
571 line - The line.
572
573 Returns: The IntersectionTypes.
574 *-----------------------------------------------------------------------------------------------**/
575 template<uint01 t_dims, class t_type, class t_vertex>
577 {
578 if (isNaN(intersection(tri, line, cast<t_type>(intersection_epsilon))))
579 return outside;
580 return mixed;
581 }
582
583 template<uint01 t_dims, class t_type, class t_vertex>
585 {
586 return polygon.template contains<t_type>(tri.template as<2, t_type>());
587 }
588 template<uint01 t_dims, class t_type, class t_vertex>
590 {
591 const PlanePosition position_a = plane.planePosition(triangle.vertex(A));
592 const PlanePosition position_b = plane.planePosition(triangle.vertex(B));
593 const PlanePosition position_c = plane.planePosition(triangle.vertex(C));
594 if (position_a == position_b && position_a == position_c)
595 {
596 if (position_a == PlanePosition::e_on_plane)
597 return mixed;
598 else
599 return outside;
600 }
601 return mixed;
602 }
603 template<uint01 t_dims, class t_type, class t_vertex>
605 {
606 const PlanePosition position_a = plane.planePosition(triangle.vertex(A));
607 const PlanePosition position_b = plane.planePosition(triangle.vertex(B));
608 const PlanePosition position_c = plane.planePosition(triangle.vertex(C));
609 if (position_a == position_b && position_a == position_c)
610 {
611 if (position_a == PlanePosition::e_on_plane)
612 return inside;
613 else
614 return outside;
615 }
616 return mixed;
617 }
618
619/////////////////////////BOUNDS CLASSIFY//////////////////////////////////
620
621 /**--------------------------------------------------------------------------------------------------
622 Fn: IntersectionTypes classify(const Bounds<t_dims, t_type, t_vertex>& bounds,
623 const t_vertex& vertex)
624
625 Classifies.
626
627 Author: Tyler Parke
628
629 Date: 2017-11-19
630
631 Parameters:
632 bounds - The bounds.
633 vertex - The vertex.
634
635 Returns: The IntersectionTypes.
636 *-----------------------------------------------------------------------------------------------**/
637 template<uint01 t_dims, class t_type, class t_vertex>
638 IntersectionTypes classify(const Bounds<t_dims, t_type, t_vertex>& bounds, const t_vertex& vertex)
639 {
640 if (bounds.contains(vertex))
641 return inside;
642 return outside;
643 }
644
645 /**--------------------------------------------------------------------------------------------------
646 Fn: IntersectionTypes classify(const Bounds<t_dims, t_type, t_vertex>& bounds,
647 const LineSegment<t_dims, t_type, t_vertex>& line)
648
649 Classifies.
650
651 Author: Tyler Parke
652
653 Date: 2017-11-19
654
655 Parameters:
656 bounds - The bounds.
657 line - The line.
658
659 Returns: The IntersectionTypes.
660 *-----------------------------------------------------------------------------------------------**/
661 template<uint01 t_dims, class t_type, class t_vertex>
663 {
664 if (bounds.contains(line))
665 {
666 return inside;
667 }
668 const Vertex<t_dims, t_type> ray = line.ray();
669 for (uint01 i = 0; i < t_dims; ++i)
670 {
671 if (bounds.doesIntersect(line.vertex(A)[i] - bounds[MIN][i], line.vertex(B)[i] - bounds[MIN][i], line.vertex(A), ray, i)
672 || bounds.doesIntersect(line.vertex(A)[i] - bounds[MAX][i], line.vertex(B)[i] - bounds[MAX][i], line.vertex(A), ray, i))
673 return mixed;
674 }
675 return outside;
676 }
677
678
679
680 /**--------------------------------------------------------------------------------------------------
681 Fn: IntersectionTypes classify(const Bounds<t_dims, t_type, t_vertex>& bounds,
682 const Triangle<t_dims, t_type, t_vertex>& tri)
683
684 Classifies.
685
686 Author: Tyler Parke
687
688 Date: 2017-11-19
689
690 Parameters:
691 bounds - The bounds.
692 tri - The triangle.
693
694 Returns: The IntersectionTypes.
695 *-----------------------------------------------------------------------------------------------**/
696 template<uint01 t_dims, class t_type, class t_vertex>
698 {
699 if (bounds.contains(tri))
700 return inside;
701 else
702 {
703 const t_vertex min = getMin(tri.vertex(A), tri.vertex(B), tri.vertex(C));
704 const t_vertex max = getMax(tri.vertex(A), tri.vertex(B), tri.vertex(C));
705 for (uint01 i = 0; i < t_dims; i++)
706 {
707 if (min[i] > bounds[MAX][i] || max[i] < bounds[MIN][i])
708 return outside;
709 }
710 }
711
712 const t_vertex bounds_center(bounds.center());
713 const Triangle<t_dims, t_type, t_vertex> centered_tri(
714 t_vertex(tri.vertex(A) - bounds_center)
715 , t_vertex(tri.vertex(B) - bounds_center)
716 , t_vertex(tri.vertex(C) - bounds_center));
717 const t_vertex half_span(bounds.span() / cast<t_type>(2));
718 const t_vertex edge[3] = { centered_tri.edge(A, B).ray(), centered_tri.edge(B, C).ray(), centered_tri.edge(C, A).ray() };
719 for (uint01 edge_index = 0; edge_index < 3; ++edge_index)
720 {
721 const t_vertex cur_edge = edge[edge_index];
722 const t_vertex abs_edge = abs(edge[edge_index]);
723 for (uint01 i = 0; i < 3; ++i)
724 {
725 t_type val_a;
726 t_type val_b;
727 t_type radius;
728 switch (i)
729 {
730 case 0:
731 val_a = cur_edge[Z] * centered_tri.vertex(A)[Y] - cur_edge[Y] * centered_tri.vertex(A)[Z];
732 val_b = cur_edge[Z] * centered_tri.vertex(C)[Y] - cur_edge[Y] * centered_tri.vertex(C)[Z];
733 radius = abs_edge[Z] * half_span[Y] + abs_edge[Y] * half_span[Z];
734 break;
735 case 1:
736 val_a = -cur_edge[Z] * centered_tri.vertex(A)[X] + cur_edge[X] * centered_tri.vertex(A)[Z];
737 val_b = -cur_edge[Z] * centered_tri.vertex(C)[X] + cur_edge[X] * centered_tri.vertex(C)[Z];
738 radius = abs_edge[Z] * half_span[X] + abs_edge[X] * half_span[Z];
739 break;
740 case 2:
741 default:
742 val_a = cur_edge[Y] * centered_tri.vertex(B)[X] - cur_edge[X] * centered_tri.vertex(B)[Y];
743 val_b = cur_edge[Y] * centered_tri.vertex(C)[X] - cur_edge[X] * centered_tri.vertex(C)[Y];
744 radius = abs_edge[Y] * half_span[X] + abs_edge[X] * half_span[Y];
745 break;
746 }
747 if (val_a < val_b)
748 {
749 if (val_a > radius || val_b < -radius)
750 return outside;
751 }
752 else
753 {
754 if (val_b > radius || val_a < -radius)
755 return outside;
756 }
757 }
758 }
759 const t_vertex normal = cross(edge[0], edge[1]);
760 t_vertex vertex_min;
761 t_vertex vertex_max;
762 for (uint01 i = 0; i < 3; i++)
763 {
764 t_type vertex_a_val = centered_tri.vertex(A)[i];
765 if (normal[i] > cast<t_type>(0))
766 {
767 vertex_min[i] = -half_span[i] - vertex_a_val;
768 vertex_max[i] = half_span[i] - vertex_a_val;
769 }
770 else
771 {
772 vertex_min[i] = half_span[i] - vertex_a_val;
773 vertex_max[i] = -half_span[i] - vertex_a_val;
774 }
775 }
776 if (dot(normal, vertex_min) > cast<t_type>(0) || dot(normal, vertex_max) < cast<t_type>(0))
777 return outside;
778 return mixed;
779 }
780
781 /**--------------------------------------------------------------------------------------------------
782 Fn: IntersectionTypes classify(const Bounds<t_dims, t_type, t_vertex>& outside,
783 const Bounds<t_dims, t_type, t_vertex>& inside)
784
785 Classifies.
786
787 Author: Tyler Parke
788
789 Date: 2017-11-19
790
791 Parameters:
792 outside - The outside.
793 inside - The inside.
794
795 Returns: The IntersectionTypes.
796 *-----------------------------------------------------------------------------------------------**/
797 template<uint01 t_dims, class t_type, class t_vertex>
799 {
800 bool is_inside = true;
801 for (uint01 dim = 0; dim < t_dims; ++dim)
802 {
803 if (!(right[MIN][dim] >= left[MIN][dim]))
804 {
805 if (!(right[MAX][dim] >= left[MIN][dim]))
806 return outside;
807 is_inside = false;
808 }
809 if (!(right[MAX][dim] <= left[MAX][dim]))
810 {
811 if (!(right[MIN][dim] <= left[MAX][dim]))
812 return outside;
813 is_inside = false;
814 }
815 }
816 if (is_inside)
817 return inside;
818 return mixed;
819 }
820
821 /**--------------------------------------------------------------------------------------------------
822 Fn: IntersectionTypes classify(const Bounds<t_dims, t_type, t_vertex>& bounds,
823 const RadialObject<t_dims, t_type, t_vertex>& radial)
824
825 Classifies.
826
827 Author: Tyler Parke
828
829 Date: 2017-11-19
830
831 Parameters:
832 bounds - The bounds.
833 radial - The radial.
834
835 Returns: The IntersectionTypes.
836 *-----------------------------------------------------------------------------------------------**/
837 template<uint01 t_dims, class t_type, class t_vertex>
839 {
840 const t_vertex center = radial.center();
841
842 uint01 inside_dims = 0;
843 t_type sqr_dist = cast<t_type>(0);
844
845 for (uint01 dim = 0; dim < t_dims; ++dim)
846 {
847 if (center[dim] < bounds[MIN][dim])
848 sqr_dist += (bounds[MIN][dim] - center[dim]) * (bounds[MIN][dim] - center[dim]);
849 else if (center[dim] > bounds[MAX][dim])
850 sqr_dist += (center[dim] - bounds[MAX][dim]) * (center[dim] - bounds[MAX][dim]);
851 else if (center[dim] >= bounds[MIN] + radial.radius() && center[dim] <= bounds[MAX][dim] - radial.radius())
852 inside_dims++;
853 }
854 if (inside_dims == t_dims)
855 return inside;
856 if (sqr_dist > radial.radius() * radial.radius())
857 return outside;
858 return mixed;
859 }
860
861
862
863 template<uint01 t_dims, class t_type, class t_vertex>
865 {
866 return polygon.template contains<t_type>(bounds.template as<2, t_type>());
867 }
868
869
870 template<uint01 t_dims, class t_type, class t_vertex>
872 {
873 t_vertex c = bounds.center(); // Compute AABB center
874 t_vertex e = bounds[MAX] - c; // Compute positive extents
875
876 // Compute the projection interval radius of b onto L(t) = b.c + t * p.n
877 t_type r = (e * abs(plane.normal)).sum();
878
879 // Compute distance of box center from plane
880 t_type s = dot(plane.normal, c) - plane.d;
881
882 // Intersection occurs when distance s falls within [-r,+r] interval
883 if (abs(s) <= r)
885 else
887 }
888
889 template<uint01 t_dims, class t_type, class t_vertex>
891 {
892 return classify(bounds, plane);
893 }
894
895/////////////////////////RADIAL OBJECT CLASSIFY/////////////////////////////////////
896 /**--------------------------------------------------------------------------------------------------
897 Fn: IntersectionTypes classify(const RadialObject<t_dims, t_type, t_vertex>& rad,
898 const t_vertex& vector)
899
900 Classifies.
901
902 Author: Tyler Parke
903
904 Date: 2017-11-19
905
906 Parameters:
907 rad - The radians.
908 vector - The vector.
909
910 Returns: The IntersectionTypes.
911 *-----------------------------------------------------------------------------------------------**/
912 template<uint01 t_dims, class t_type, class t_vertex>
914 {
915 if (rad.contains(vector))
916 return inside;
917 return outside;
918 }
919 /**--------------------------------------------------------------------------------------------------
920 Fn: IntersectionTypes classify(const RadialObject<t_dims, t_type, t_vertex>& radial,
921 const Bounds<t_dims, t_type, t_vertex>& bounds)
922
923 Classifies.
924
925 Author: Tyler Parke
926
927 Date: 2017-11-19
928
929 Parameters:
930 radial - The radial.
931 bounds - The bounds.
932
933 Returns: The IntersectionTypes.
934 *-----------------------------------------------------------------------------------------------**/
935 template<uint01 t_dims, class t_type, class t_vertex>
937 {
938 t_type max_tot(0);
939 t_type min_tot(0);
940 for (uint01 i = 0; i < t_dims; i++)
941 {
942 const t_type cir_center = radial.center()[i];
943 const t_type dist_max = (bounds[MAX][i] - cir_center) * (bounds[MAX][i] - cir_center);
944 const t_type dist_min = (bounds[MIN][i] - cir_center) * (bounds[MIN][i] - cir_center);
945 if (dist_max > dist_min)
946 {
947 max_tot += dist_max;
948 if (cir_center < bounds[MIN][i])
949 min_tot += dist_min;
950 }
951 else
952 {
953 max_tot += dist_min;
954 if (cir_center > bounds[MAX][i])
955 min_tot += dist_max;
956 }
957 }
958 const t_type rad_squared = radial.radius() * radial.radius();
959 if (max_tot < rad_squared)
960 return inside;
961 if (min_tot < rad_squared)
962 return mixed;
963 return outside;
964 }
965 template<uint01 t_dims, class t_type, class t_vertex>
967 {
968 t_vertex c = radial.center(); // Compute AABB
969 if (radial.radius() >= plane.distanceTo(c))
970 return mixed;
971 else
972 return outside;
973 }
974 template<uint01 t_dims, class t_type, class t_vertex>
976 {
977 return classify(radial, plane);
978 }
979
980 template<class t_type, class t_vertex>
981 IntersectionTypes classify(const Polygon<t_type, t_vertex>& polygon, const t_vertex& vector)
982 {
983 if (polygon.contains(vector))
984 return inside;
985 return outside;
986 }
987
988
989 template<uint01 t_dims, class t_type, class t_vertex>
991 {
992 return polygon.template contains<t_type>(bounds.template as<2, t_type>());
993 }
994
995
996 template<uint01 t_dims, class t_type, class t_vertex>
998 {
999 return polygon.template contains<t_type>(tri.template as<2, t_type>());
1000 }
1001
1002
1003 template<uint01 t_dims, class t_type, class t_vertex>
1005 {
1006 return polygon.template contains<t_type>(line.template as<2, t_type>());
1007 }
1008
1009
1010
1011}
1012
#define UNUSED(expr)
Definition BaseValues.hpp:433
A specification of upper and lower bounds in N-dimensions.
Definition Bounds.hpp:57
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:139
constexpr bool contains(const t_type &value) const
Query if this object contains the given value.
Definition Bounds.hpp:329
constexpr t_vertex center() const
Returns the center of the bounds.
Definition Bounds.hpp:156
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:701
Definition Intersection.hpp:47
A line segment represented by two vertices, a start and end.
Definition Line.hpp:55
constexpr t_vertex ray() const
Definition Line.hpp:134
constexpr const t_vertex & vertex(uint01 index) const
Definition Line.hpp:171
constexpr t_type lengthSquared() const
Definition Line.hpp:505
Definition Geometry.h:41
t_type d
Definition Plane.hpp:216
t_type distanceTo(const Vector< t_dims, t_type > &pos) const
Definition Plane.hpp:103
PlanePosition planePosition(const Vector< t_dims, t_type > &pos) const
Definition Plane.hpp:81
Ray< t_dims, t_type > normal
Definition Plane.hpp:215
bool contains(const Vector< 3, t_type > &point, t_type epsilon) const
Definition Plane.hpp:195
An N-sided polygon.
Definition Polygon.hpp:58
bool contains(const Vertex< 2, t_type > &vector) const
Definition Polygon.hpp:515
A radial object.
Definition RadialObject.hpp:57
constexpr t_type radius() const
Definition RadialObject.hpp:134
constexpr const t_vertex & center() const
Definition RadialObject.hpp:167
constexpr bool contains(const t_vertex &vector) const
Definition RadialObject.hpp:114
Definition Triangle.hpp:143
constexpr bool contains(const Vector< t_dims - 1, t_type > &p) const
Definition Triangle.hpp:481
constexpr t_vertex & vertex(TriangleLocation triangle_node)
Vertices the given triangle node.
Definition Triangle.hpp:180
constexpr LineSegment< t_dims, t_type, t_vertex > edge(uint01 triangle_node_a, uint01 triangle_node_b) const
Definition Triangle.hpp:276
An element of a vector space. An element of the real coordinate space Rn Basis vector,...
Definition Vector.hpp:62
A vertex.
Definition Vertex.hpp:54
Definition ACIColor.h:37
constexpr t_type getMax(const t_type &left, const t_type &right)
Finds the max of the given arguments using the > operator.
Definition BaseFunctions.hpp:116
t_type dot(const Vector< t_dims, t_type > &v1, const Vector< t_dims, t_type > &v2)
Definition VectorFunctions.hpp:1096
@ MIN
Definition BaseValues.hpp:226
@ MAX
Definition BaseValues.hpp:227
@ edge_ca
Definition Triangle.hpp:56
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:98
t_type distanceSquared(const Bounds< t_dims, t_type, t_vertex > &bounds, const Vector< t_dims, t_type > &vertex)
Definition Distance.hpp:42
IntersectionTypes
Used for classifying shape intersections.
Definition BaseValues.hpp:241
@ inside
Definition BaseValues.hpp:243
@ mixed
Definition BaseValues.hpp:244
@ outside
Definition BaseValues.hpp:242
constexpr fltp08 intersection_epsilon
Definition Intersection.hpp:48
PlanePosition
Definition Plane.hpp:39
constexpr Vector< 1, t_type > cross(const Vector< 1, t_type > &, const Vector< 1, t_type > &)
Definition VectorFunctions.hpp:954
IntersectionTypes classify(const Vector< t_dims, t_type > &v1, const Vector< t_dims, t_type > &v2)
Definition Intersection.hpp:338
constexpr t_to cast(const Angle< t_from > &value)
Definition Angle.h:514
constexpr Angle< t_angle_type > abs(const Angle< t_angle_type > &value)
Definition AngleFunctions.h:750
constexpr bool isNaN(const t_type &value)
Query if 'value' is valid or invalid.
Definition BaseFunctions.hpp:200
@ B
Definition BaseValues.hpp:203
@ A
Definition BaseValues.hpp:201
@ Y
Definition BaseValues.hpp:202
@ X
Definition BaseValues.hpp:200
@ C
Definition BaseValues.hpp:205
@ Z
Definition BaseValues.hpp:204
double fltp08
Defines an alias representing an 8 byte floating-point number.
Definition BaseValues.hpp:181
constexpr t_type getMin(const t_type &left, const t_type &right)
Finds the minimum of the given arguments based on the < operator.
Definition BaseFunctions.hpp:67
static const t_type NaN
Definition BaseValues.hpp:274