point_segment_squared_distance.cpp 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  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_segment_squared_distance.h"
  9. template < typename Kernel>
  10. IGL_INLINE void igl::copyleft::cgal::point_segment_squared_distance(
  11. const CGAL::Point_3<Kernel> & P1,
  12. const CGAL::Segment_3<Kernel> & S2,
  13. CGAL::Point_3<Kernel> & P2,
  14. typename Kernel::FT & d)
  15. {
  16. if(S2.is_degenerate())
  17. {
  18. P2 = S2.source();
  19. d = (P1-P2).squared_length();
  20. return;
  21. }
  22. // http://stackoverflow.com/a/1501725/148668
  23. const auto sqr_len = S2.squared_length();
  24. assert(sqr_len != 0);
  25. const auto & V = S2.source();
  26. const auto & W = S2.target();
  27. const auto t = (P1-V).dot(W-V)/sqr_len;
  28. if(t<0)
  29. {
  30. P2 = V;
  31. }else if(t>1)
  32. {
  33. P2 = W;
  34. }else
  35. {
  36. P2 = V + t*(W-V);
  37. }
  38. d = (P1-P2).squared_length();
  39. }