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>
67 template<u
int01 t_dims,
class t_type,
class t_vertex>
91 template<u
int01 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)
94 LineSegment<t_dims, t_type> intersected_line = line;
95 for (
uint01 dim = 0; dim < t_dims; ++dim)
97 if (intersected_line.vertex(
A)[dim] < bounds[
MIN][dim])
99 if (intersected_line.vertex(
B)[dim] < bounds[
MIN][dim])
100 return Constant<LineSegment<t_dims, t_type>>::NaN;
102 intersected_line.vertex(
A) = line.template pointAt<true>(bounds[
MIN][dim], dim);
104 else if (intersected_line.vertex(
B)[dim] < bounds[
MIN][dim])
106 intersected_line.vertex(
B) = line.template pointAt<true>(bounds[
MIN][dim], dim);
108 if (intersected_line.vertex(
A)[dim] > bounds[
MAX][dim])
110 if (intersected_line.vertex(
B)[dim] > bounds[
MAX][dim])
111 return Constant<LineSegment<t_dims, t_type>>::NaN;
113 intersected_line.vertex(
A) = line.template pointAt<true>(bounds[
MAX][dim], dim);
115 else if (intersected_line.vertex(
B)[dim] > bounds[
MAX][dim])
117 intersected_line.vertex(
B) = line.template pointAt<true>(bounds[
MAX][dim], dim);
120 return intersected_line;
140 template<u
int01 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)
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)
151 const t_vertex t = line.vertex(
A) - tri.vertex(
A);
152 const t_type u0 =
dot(t, cross_line_tri) / determinant;
155 const t_vertex q =
cross(t, tri_edge_ab);
156 const t_type v =
dot(line_ray, q) / determinant;
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);
186 template<u
int01 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)
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;
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;
200 if (dot_1a == 0 || dot_1b == 0 || dot_1c == 0)
202 return Constant<LineSegment<t_dims, t_type, t_vertex>>::NaN;
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));
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;
211 if (dot_2a == 0 || dot_2b == 0 || dot_2c == 0)
212 return Constant<LineSegment<t_dims, t_type, t_vertex>>::NaN;
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)));
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)));
220 const t_vertex cross_normal =
cross(normal_a, normal_b).template normalized<t_type>();
222 const t_type tp13 =
dot(seg_a2 - seg_a1, cross_normal);
226 const t_type tq12 =
dot(seg_b1 - seg_a1, cross_normal);
227 const t_type tq13 =
dot(seg_b2 - seg_a1, cross_normal);
229 const t_type Iq1 =
getMin(tq12, tq13);
230 const t_type Iq2 =
getMax(tq12, tq13);
233 if (
abs(Ip1 - Iq1) * 2 < ((Ip2 - Ip1) + (Iq2 - Iq1)))
235 t_type n_b =
getMax(Ip1, Iq1);
236 t_type n_a =
getMin(Ip2, Iq2);
239 return LineSegment<t_dims, t_type, t_vertex>(seg_a1 + cross_normal * n_a, seg_a1 + cross_normal * n_b);
242 return Constant<LineSegment<t_dims, t_type, t_vertex>>::NaN;
265 template<u
int01 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)
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;
275 if (signed_dist_a == 0.0)
277 if (signed_dist_b == 0.0)
279 if (signed_dist_c != 0.0)
281 seg[
A] = tri_a.vertex(
A);
282 seg[
B] = tri_a.vertex(
B);
286 else if (signed_dist_c == 0.0)
288 seg[
A] = tri_a.vertex(
A);
289 seg[
B] = tri_a.vertex(
C);
294 seg[seg_location++] = tri_a.vertex(
A);
297 if (signed_dist_b == 0.0)
299 if (signed_dist_c == 0.0)
301 seg[
A] = tri_a.vertex(
B);
302 seg[
B] = tri_a.vertex(
C);
305 seg[seg_location++] = tri_a.vertex(
B);
307 if (signed_dist_c == 0.0)
309 seg[seg_location++] = tri_a.vertex(
C);
311 if (signed_dist_a * signed_dist_b < 0)
313 t_type t = signed_dist_a / (signed_dist_a - signed_dist_b);
314 seg[seg_location++] = tri_a.vertex(
A) + t * (tri_a.vertex(
B) - tri_a.vertex(
A));
316 if (signed_dist_b * signed_dist_c < 0)
318 t_type t = signed_dist_b / (signed_dist_b - signed_dist_c);
319 seg[seg_location++] = tri_a.vertex(
B) + t * (tri_a.vertex(
C) - tri_a.vertex(
B));
321 if (signed_dist_c * signed_dist_a < 0)
323 t_type t = signed_dist_c / (signed_dist_c - signed_dist_a);
324 seg[seg_location++] = tri_a.vertex(
C) + t * (tri_a.vertex(
A) - tri_a.vertex(
C));
328 template<u
int01 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)
331 return intersection(tri_a, plane, epsilon);
337 template<u
int01 t_dims,
class t_type>
345 template<u
int01 t_dims,
class t_type,
class t_vertex>
368 template<u
int01 t_dims,
class t_type,
class t_vertex>
393 template<u
int01 t_dims,
class t_type,
class t_vertex>
401 template<
class t_type,
class t_vertex>
410 template<u
int01 t_dims,
class t_type,
class t_vertex>
419 template<u
int01 t_dims,
class t_type,
class t_vertex>
449 template<u
int01 t_dims,
class t_type,
class t_vertex>
455 t_vertex dir = line.
ray().template normalized<t_type>();
457 t_type det =
dot(edge_ba, pvec);
460 if (
abs(det) < epsilon)
465 t_type u =
dot(tvec, pvec) * invDet;
469 t_vertex qvec(
cross(tvec, edge_ba));
470 t_type v =
dot(dir, qvec) * invDet;
495 template<u
int01 t_dims,
class t_type,
class t_vertex>
500 template<u
int01 t_dims,
class t_type,
class t_vertex>
503 return polygon.template contains<t_type>(line.template as<2, t_type>());
507 template<u
int01 t_dims,
class t_type,
class t_vertex>
514 template<u
int01 t_dims,
class t_type,
class t_vertex>
521 template<u
int01 t_dims,
class t_type,
class t_vertex>
526 if (position_a == position_b)
535 template<u
int01 t_dims,
class t_type,
class t_vertex>
540 if (position_a == position_b)
552 template<u
int01 t_dims,
class t_type,
class t_vertex>
575 template<u
int01 t_dims,
class t_type,
class t_vertex>
583 template<u
int01 t_dims,
class t_type,
class t_vertex>
586 return polygon.template contains<t_type>(tri.template as<2, t_type>());
588 template<u
int01 t_dims,
class t_type,
class t_vertex>
594 if (position_a == position_b && position_a == position_c)
603 template<u
int01 t_dims,
class t_type,
class t_vertex>
609 if (position_a == position_b && position_a == position_c)
637 template<u
int01 t_dims,
class t_type,
class t_vertex>
661 template<u
int01 t_dims,
class t_type,
class t_vertex>
669 for (
uint01 i = 0; i < t_dims; ++i)
696 template<u
int01 t_dims,
class t_type,
class t_vertex>
705 for (
uint01 i = 0; i < t_dims; i++)
707 if (min[i] > bounds[
MAX][i] || max[i] < bounds[
MIN][i])
712 const t_vertex bounds_center(bounds.
center());
714 t_vertex(tri.
vertex(
A) - bounds_center)
715 , t_vertex(tri.
vertex(
B) - bounds_center)
716 , t_vertex(tri.
vertex(
C) - bounds_center));
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)
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)
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];
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];
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];
749 if (val_a > radius || val_b < -radius)
754 if (val_b > radius || val_a < -radius)
759 const t_vertex normal =
cross(edge[0], edge[1]);
762 for (
uint01 i = 0; i < 3; i++)
764 t_type vertex_a_val = centered_tri.
vertex(
A)[i];
767 vertex_min[i] = -half_span[i] - vertex_a_val;
768 vertex_max[i] = half_span[i] - vertex_a_val;
772 vertex_min[i] = half_span[i] - vertex_a_val;
773 vertex_max[i] = -half_span[i] - vertex_a_val;
797 template<u
int01 t_dims,
class t_type,
class t_vertex>
800 bool is_inside =
true;
801 for (
uint01 dim = 0; dim < t_dims; ++dim)
803 if (!(right[
MIN][dim] >= left[
MIN][dim]))
805 if (!(right[
MAX][dim] >= left[
MIN][dim]))
809 if (!(right[
MAX][dim] <= left[
MAX][dim]))
811 if (!(right[
MIN][dim] <= left[
MAX][dim]))
837 template<u
int01 t_dims,
class t_type,
class t_vertex>
840 const t_vertex center = radial.
center();
845 for (
uint01 dim = 0; dim < t_dims; ++dim)
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())
854 if (inside_dims == t_dims)
863 template<u
int01 t_dims,
class t_type,
class t_vertex>
866 return polygon.template contains<t_type>(bounds.template as<2, t_type>());
870 template<u
int01 t_dims,
class t_type,
class t_vertex>
873 t_vertex c = bounds.
center();
874 t_vertex e = bounds[
MAX] - c;
877 t_type r = (e *
abs(plane.
normal)).sum();
889 template<u
int01 t_dims,
class t_type,
class t_vertex>
912 template<u
int01 t_dims,
class t_type,
class t_vertex>
935 template<u
int01 t_dims,
class t_type,
class t_vertex>
940 for (
uint01 i = 0; i < t_dims; i++)
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)
948 if (cir_center < bounds[
MIN][i])
954 if (cir_center > bounds[
MAX][i])
958 const t_type rad_squared = radial.
radius() * radial.
radius();
959 if (max_tot < rad_squared)
961 if (min_tot < rad_squared)
965 template<u
int01 t_dims,
class t_type,
class t_vertex>
968 t_vertex c = radial.
center();
974 template<u
int01 t_dims,
class t_type,
class t_vertex>
980 template<
class t_type,
class t_vertex>
989 template<u
int01 t_dims,
class t_type,
class t_vertex>
992 return polygon.template contains<t_type>(bounds.template as<2, t_type>());
996 template<u
int01 t_dims,
class t_type,
class t_vertex>
999 return polygon.template contains<t_type>(tri.template as<2, t_type>());
1003 template<u
int01 t_dims,
class t_type,
class t_vertex>
1006 return polygon.template contains<t_type>(line.template as<2, t_type>());
#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
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
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