MCPcopy Create free account
hub / github.com/Geode-solutions/OpenGeode / line_triangle_intersection

Function line_triangle_intersection

src/geode/geometry/intersection.cpp:344–413  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

342 }
343
344 IntersectionResult< Point3D > line_triangle_intersection(
345 const InfiniteLine3D& line, const Triangle3D& triangle )
346 {
347 // http://www.geometrictools.com/LibMathematics/Intersection/Intersection.html
348 // Compute the offset origin, edges, and normal.
349 const auto& vertices = triangle.vertices();
350 const Vector3D edge1{ vertices[0], vertices[1] };
351 const Vector3D edge2{ vertices[0], vertices[2] };
352 const auto normal = edge1.cross( edge2 );
353
354 // Solve Q + t*D = b1*E1 + b2*E2 (Q = diff, D = segment direction,
355 // E1 = edge1, E2 = edge2, N = Cross(E1,E2)) by
356 // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
357 // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
358 // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
359 auto d_dot_n = line.direction().dot( normal );
360 signed_index_t sign;
361 if( d_dot_n > 0. )
362 {
363 sign = 1;
364 }
365 else if( d_dot_n < -0. )
366 {
367 sign = -1;
368 d_dot_n = -d_dot_n;
369 }
370 else
371 {
372 // Segment and triangle are parallel
373 return { INTERSECTION_TYPE::parallel };
374 }
375
376 const Vector3D diff{ vertices[0], line.origin() };
377 const auto d_dot_q_cross_e2 =
378 sign * line.direction().dot( diff.cross( edge2 ) );
379 if( d_dot_q_cross_e2 >= -GLOBAL_EPSILON )
380 {
381 const auto d_dot_e1_cross_q =
382 sign * line.direction().dot( edge1.cross( diff ) );
383 if( d_dot_e1_cross_q >= -GLOBAL_EPSILON
384 && d_dot_q_cross_e2 + d_dot_e1_cross_q <= d_dot_n )
385 {
386 // InfiniteLine intersects triangle.
387 const auto q_dot_n = -sign * diff.dot( normal );
388 const auto inv = 1. / d_dot_n;
389 const auto seg_parameter = q_dot_n * inv;
390
391 auto result = line.origin() + line.direction() * seg_parameter;
392 CorrectnessInfo< Point3D >::Correctness first_correctness{
393 point_line_distance( result, line ) <= GLOBAL_EPSILON,
394 point_line_projection( result, line )
395 };
396 const auto tri_lambdas =
397 safe_triangle_barycentric_coordinates( result, triangle );
398 const auto correctness_point =
399 vertices[0].get() * tri_lambdas[0]
400 + vertices[1].get() * tri_lambdas[1]
401 + vertices[2].get() * tri_lambdas[2];

Callers

nothing calls this directly

Calls 8

point_line_distanceFunction · 0.85
point_line_projectionFunction · 0.85
crossMethod · 0.80
dotMethod · 0.80
directionMethod · 0.45
getMethod · 0.45
inexact_equalMethod · 0.45

Tested by

no test coverage detected