triangle_triangle_squared_distance.cpp 3.2 KB

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