@@ -339,6 +339,79 @@ namespace
339339 geode::point_point_distance ( point, closest_point );
340340 return std::make_tuple ( distance, std::move ( closest_point ) );
341341 }
342+
343+ std::pair< std::vector< geode::local_index_t >,
344+ std::vector< geode::local_index_t > >
345+ find_non_colocated_triangles_points ( const geode::Triangle3D& triangle0,
346+ const geode::Triangle3D& triangle1 )
347+ {
348+ std::pair< std::array< bool , 3 >, std::array< bool , 3 > > colocated{
349+ { false , false , false }, { false , false , false }
350+ };
351+ const auto & vertices0 = triangle0.vertices ();
352+ const auto & vertices1 = triangle1.vertices ();
353+ for ( const auto vertex0 : geode::LRange{ 3 } )
354+ {
355+ for ( const auto vertex1 : geode::LRange{ 3 } )
356+ {
357+ if ( geode::point_point_distance (
358+ vertices0[vertex0].get (), vertices1[vertex1].get () )
359+ <= geode::GLOBAL_EPSILON )
360+ {
361+ colocated.first [vertex0] = true ;
362+ colocated.second [vertex1] = true ;
363+ }
364+ }
365+ }
366+
367+ std::pair< std::vector< geode::local_index_t >,
368+ std::vector< geode::local_index_t > >
369+ result;
370+ for ( const auto v : geode::LRange{ 3 } )
371+ {
372+ if ( !colocated.first [v] )
373+ {
374+ result.first .push_back ( v );
375+ }
376+ if ( !colocated.second [v] )
377+ {
378+ result.second .push_back ( v );
379+ }
380+ }
381+ return result;
382+ }
383+
384+ std::tuple< double , geode::Point3D, geode::Point3D > test_close_triangles (
385+ const std::vector< geode::local_index_t >& non_colocated_points,
386+ const geode::Triangle3D& base_triangle,
387+ const geode::Triangle3D& other_triangle )
388+ {
389+ const auto & base_vertices = base_triangle.vertices ();
390+ double min_distance{ std::numeric_limits< double >::max () };
391+ geode::Point3D point0;
392+ geode::Point3D point1;
393+ for ( const auto vertex0 : non_colocated_points )
394+ {
395+ for ( const auto vertex1 : non_colocated_points )
396+ {
397+ if ( vertex0 == vertex1 )
398+ {
399+ continue ;
400+ }
401+ const geode::Segment3D edge{ base_vertices[vertex0],
402+ base_vertices[vertex1] };
403+ auto [cur_distance, cur_pt0, cur_pt1] =
404+ geode::segment_triangle_distance ( edge, other_triangle );
405+ if ( cur_distance < min_distance )
406+ {
407+ min_distance = cur_distance;
408+ point0 = cur_pt0;
409+ point1 = cur_pt1;
410+ }
411+ }
412+ }
413+ return std::make_tuple ( min_distance, point0, point1 );
414+ }
342415} // namespace
343416
344417namespace geode
@@ -923,6 +996,112 @@ namespace geode
923996 closest_on_segment, closest_on_triangle );
924997 }
925998
999+ std::tuple< double , Point3D, Point3D >
1000+ opengeode_geometry_api triangle_triangle_distance (
1001+ const Triangle3D& triangle0, const Triangle3D& triangle1 )
1002+ {
1003+ const auto non_colocated_points =
1004+ find_non_colocated_triangles_points ( triangle0, triangle1 );
1005+ if ( non_colocated_points.first .size () < 3 )
1006+ {
1007+ for ( const auto v : LRange{ 3 } )
1008+ {
1009+ if ( !absl::c_contains ( non_colocated_points.first , v ) )
1010+ {
1011+ auto & pt0 = triangle0.vertices ()[v].get ();
1012+ auto [distance, pt1] =
1013+ point_triangle_distance ( pt0, triangle1 );
1014+ return std::make_tuple ( distance, pt0, pt1 );
1015+ }
1016+ }
1017+ }
1018+ if ( non_colocated_points.second .size () < 3 )
1019+ {
1020+ for ( const auto v : LRange{ 3 } )
1021+ {
1022+ if ( !absl::c_contains ( non_colocated_points.second , v ) )
1023+ {
1024+ auto & pt1 = triangle1.vertices ()[v].get ();
1025+ auto [distance, pt0] =
1026+ point_triangle_distance ( pt1, triangle0 );
1027+ return std::make_tuple ( distance, pt0, pt1 );
1028+ }
1029+ }
1030+ }
1031+ auto [cur_distance0, cur_pt00, cur_pt01] = test_close_triangles (
1032+ non_colocated_points.first , triangle0, triangle1 );
1033+ auto [cur_distance1, cur_pt11, cur_pt10] = test_close_triangles (
1034+ non_colocated_points.second , triangle1, triangle0 );
1035+ if ( cur_distance0 < cur_distance1 )
1036+ {
1037+ return std::make_tuple ( cur_distance0, cur_pt00, cur_pt01 );
1038+ }
1039+ return std::make_tuple ( cur_distance1, cur_pt10, cur_pt11 );
1040+ }
1041+
1042+ std::optional< std::tuple< double , Point3D, Point3D > >
1043+ triangle_triangle_non_conformal_distance (
1044+ const Triangle3D& triangle0, const Triangle3D& triangle1 )
1045+ {
1046+ const auto non_colocated_points =
1047+ find_non_colocated_triangles_points ( triangle0, triangle1 );
1048+ if ( non_colocated_points.first .size () == 0
1049+ || non_colocated_points.second .size () == 0 )
1050+ {
1051+ return std::nullopt ;
1052+ }
1053+ const auto & vertices0 = triangle0.vertices ();
1054+ const auto & vertices1 = triangle1.vertices ();
1055+ double min_distance{ std::numeric_limits< double >::max () };
1056+ Point3D point0;
1057+ Point3D point1;
1058+ if ( non_colocated_points.first .size () == 1 )
1059+ {
1060+ auto [cur_distance, cur_pt] = point_triangle_distance (
1061+ vertices0[non_colocated_points.first [0 ]].get (), triangle1 );
1062+ if ( cur_distance < min_distance )
1063+ {
1064+ min_distance = cur_distance;
1065+ point0 = vertices0[non_colocated_points.first [0 ]].get ();
1066+ point1 = cur_pt;
1067+ }
1068+ }
1069+ if ( non_colocated_points.second .size () == 1 )
1070+ {
1071+ auto [cur_distance, cur_pt] = point_triangle_distance (
1072+ vertices1[non_colocated_points.second [0 ]].get (), triangle0 );
1073+ if ( cur_distance < min_distance )
1074+ {
1075+ min_distance = cur_distance;
1076+ point0 = cur_pt;
1077+ point1 = vertices1[non_colocated_points.second [0 ]].get ();
1078+ }
1079+ }
1080+ if ( non_colocated_points.first .size () > 1 )
1081+ {
1082+ auto [cur_distance, cur_pt0, cur_pt1] = test_close_triangles (
1083+ non_colocated_points.first , triangle0, triangle1 );
1084+ if ( cur_distance < min_distance )
1085+ {
1086+ min_distance = cur_distance;
1087+ point0 = cur_pt0;
1088+ point1 = cur_pt1;
1089+ }
1090+ }
1091+ if ( non_colocated_points.second .size () > 1 )
1092+ {
1093+ auto [cur_distance, cur_pt1, cur_pt0] = test_close_triangles (
1094+ non_colocated_points.second , triangle1, triangle0 );
1095+ if ( cur_distance < min_distance )
1096+ {
1097+ min_distance = cur_distance;
1098+ point0 = cur_pt0;
1099+ point1 = cur_pt1;
1100+ }
1101+ }
1102+ return std::make_tuple ( min_distance, point0, point1 );
1103+ }
1104+
9261105 std::tuple< double , Point3D > point_tetrahedron_distance (
9271106 const Point3D& point, const Tetrahedron& tetra )
9281107 {
@@ -1048,7 +1227,8 @@ namespace geode
10481227 }
10491228 OPENGEODE_ASSERT (
10501229 !circle.plane ().normal ().inexact_equal ( other_direction ),
1051- " [point_circle_distance] Problem while getting circle nearest "
1230+ " [point_circle_distance] Problem while getting circle "
1231+ " nearest "
10521232 " point" );
10531233 const Vector3D other_projected_on_plane =
10541234 other_direction
0 commit comments