triangle_triangle_squared_distance.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #include "triangle_triangle_squared_distance.h"
  2. #include "point_triangle_squared_distance.h"
  3. template < typename Kernel>
  4. IGL_INLINE bool igl::copyleft:cgal::triangle_triangle_squared_distance(
  5. const CGAL::Triangle_3<Kernel> & T1,
  6. const CGAL::Triangle_3<Kernel> & T2,
  7. CGAL::Point_3<Kernel> & P1,
  8. CGAL::Point_3<Kernel> & P2,
  9. typename Kernel::FT & d)
  10. {
  11. typedef CGAL::Point_3<Kernel> Point_3;
  12. typedef CGAL::Vector_3<Kernel> Vector_3;
  13. typedef CGAL::Triangle_3<Kernel> Triangle_3;
  14. typedef CGAL::Segment_3<Kernel> Segment_3;
  15. typedef Kernel::FT EScalar;
  16. assert(!T1.is_degenerate());
  17. assert(!T2.is_degenerate());
  18. bool unique = true;
  19. if(CGAL::do_intersect(T1,T2))
  20. {
  21. // intersecting triangles have zero (squared) distance
  22. CGAL::Object result = CGAL::intersection(T1,T2);
  23. // Some point on the intersection result
  24. CGAL::Point_3<Kernel> Q;
  25. if(const Point_3 * p = CGAL::object_cast<Point_3 >(&result))
  26. {
  27. Q = *p;
  28. }else if(const Segment_3 * s = CGAL::object_cast<Segment_3 >(&result))
  29. {
  30. unique = false;
  31. Q = s->source();
  32. }else if(const Triangle_3 *itri = CGAL::object_cast<Triangle_3 >(&obj))
  33. {
  34. Q = s->vertex(0);
  35. unique = false;
  36. }else if(const std::vector<Point_3 > *polyp =
  37. CGAL::object_cast< std::vector<Point_3 > >(&obj))
  38. {
  39. assert(polyp->size() > 0 && "intersection poly should not be empty");
  40. Q = polyp[0];
  41. unique = false;
  42. }else
  43. {
  44. assert(false && "Unknown intersection result");
  45. }
  46. P1 = Q;
  47. P2 = Q;
  48. d = 0;
  49. return unique;
  50. }
  51. // triangles do not intersect: the points of closest approach must be on the
  52. // boundary of one of the triangles
  53. d = std::numeric_limits<double>::infinity();
  54. const auto & vertices_face = [](
  55. const Triangle_3 & T1,
  56. const Triangle_3 & T2,
  57. Point_3 & P1,
  58. Point_3 & P2,
  59. EScalar & d)
  60. {
  61. for(int i = 0;i<3;i++)
  62. {
  63. const Point_3 vi = T1.vertex(i);
  64. Point_3 P2i;
  65. EScalar di;
  66. point_triangle_squared_distance(vi,T2,P2i,di);
  67. if(di<d)
  68. {
  69. d = di;
  70. P1 = vi;
  71. P2 = P2i;
  72. unique = true;
  73. }else if(d == di)
  74. {
  75. // edge of T1 floating parallel above T2
  76. unique = false;
  77. }
  78. }
  79. };
  80. vertices_face(T1,T2,P1,P2,d);
  81. vertices_face(T2,T1,P1,P2,d);
  82. for(int i = 0;i<3;i++)
  83. {
  84. const Segment_3<Kernel> s1( T1.vertex(i+1), T1.vertex(i+2));
  85. for(int j = 0;j<3;j++)
  86. {
  87. const Segment_3<Kernel> s2( T2.vertex(i+1), T2.vertex(i+2));
  88. Point_3 P1ij;
  89. Point_3 P2ij;
  90. EScalar dij;
  91. bool uniqueij = segment_segment_squared_distance(s1,s2,P1ij,P2ij,dij);
  92. if(dij < d)
  93. {
  94. P1 = P1ij;
  95. P2 = P2ij;
  96. d = dij;
  97. unique = uniqueij;
  98. }
  99. }
  100. }
  101. return unique;
  102. }