point_triangle_squared_distance.cpp 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  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 "point_triangle_squared_distance.h"
  9. #include <CGAL/Segment_3.h>
  10. template < typename Kernel>
  11. IGL_INLINE void point_triangle_squared_distance(
  12. const CGAL::Point_3<Kernel> & P1,
  13. const CGAL::Triangle_3<Kernel> & T2,
  14. CGAL::Point_3<Kernel> & P2,
  15. typename Kernel::FT & d)
  16. {
  17. assert(!T2.is_degenerate());
  18. if(T2.has_on(P1))
  19. {
  20. P2 = P1;
  21. d = 0;
  22. return;
  23. }
  24. const auto proj_1 = T2.supporting_plane().projection(P2);
  25. if(T2.has_on(proj_1))
  26. {
  27. P2 = proj_1;
  28. d = (proj_1-P1).squared_length();
  29. return;
  30. }
  31. // closest point must be on the boundary
  32. bool first = true;
  33. // loop over edges
  34. for(int i=0;i<3;i++)
  35. {
  36. CGAL::Point_3<Kernel> P2i;
  37. typename Kernel::FT di;
  38. const CGAL::Segment_3<Kernel> si( T2.vertex(i+1), T2.vertex(i+2));
  39. point_segment_squared_distance(P1,si,P2i,di);
  40. if(first || di < d)
  41. {
  42. first = false;
  43. d = di;
  44. P2 = P2i;
  45. }
  46. }
  47. }