triangle_triangle_squared_distance.cpp 3.1 KB

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