hausdorff.cpp 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 Alec Jacobson <[email protected]>
  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 "hausdorff.h"
  9. #include "point_mesh_squared_distance.h"
  10. template <
  11. typename DerivedVA,
  12. typename DerivedFA,
  13. typename DerivedVB,
  14. typename DerivedFB,
  15. typename Scalar>
  16. IGL_INLINE void igl::hausdorff(
  17. const Eigen::MatrixBase<DerivedVA> & VA,
  18. const Eigen::MatrixBase<DerivedFA> & FA,
  19. const Eigen::MatrixBase<DerivedVB> & VB,
  20. const Eigen::MatrixBase<DerivedFB> & FB,
  21. Scalar & d)
  22. {
  23. assert(VA.cols() == 3 && "VA should contain 3d points");
  24. assert(FA.cols() == 3 && "FA should contain triangles");
  25. assert(VB.cols() == 3 && "VB should contain 3d points");
  26. assert(FB.cols() == 3 && "FB should contain triangles");
  27. Eigen::Matrix<typename DerivedVA::Scalar, Eigen::Dynamic, 1> sqr_DBA, sqr_DAB;
  28. Eigen::Matrix<typename DerivedVA::Index ,Eigen::Dynamic,1> I;
  29. Eigen::Matrix<typename DerivedVA::Scalar ,Eigen::Dynamic,3> C;
  30. point_mesh_squared_distance(VB,VA,FA,sqr_DBA,I,C);
  31. point_mesh_squared_distance(VA,VB,FB,sqr_DAB,I,C);
  32. const Scalar dba = sqr_DBA.maxCoeff();
  33. const Scalar dab = sqr_DAB.maxCoeff();
  34. d = sqrt(std::max(dba,dab));
  35. }
  36. template <
  37. typename DerivedV,
  38. typename Scalar>
  39. IGL_INLINE void igl::hausdorff(
  40. const Eigen::MatrixBase<DerivedV>& V,
  41. const std::function<Scalar(const Scalar &,const Scalar &, const Scalar &)> & dist_to_B,
  42. Scalar & l,
  43. Scalar & u)
  44. {
  45. // e 3-long vector of opposite edge lengths
  46. Eigen::Matrix<typename DerivedV::Scalar,1,3> e;
  47. // Maximum edge length
  48. Scalar e_max = 0;
  49. for(int i=0;i<3;i++)
  50. {
  51. e(i) = (V.row((i+1)%3)-V.row((i+2)%3)).norm();
  52. e_max = std::max(e_max,e(i));
  53. }
  54. // Semiperimeter
  55. const Scalar s = (e(0)+e(1)+e(2))*0.5;
  56. // Area
  57. const Scalar A = sqrt(s*(s-e(0))*(s-e(1))*(s-e(2)));
  58. // Circumradius
  59. const Scalar R = e(0)*e(1)*e(2)/(4.*A);
  60. // inradius
  61. const Scalar r = A/s;
  62. // Initialize lower bound to ∞
  63. l = std::numeric_limits<Scalar>::infinity();
  64. // d 3-long vector of distance from each corner to B
  65. Eigen::Matrix<typename DerivedV::Scalar,1,3> d;
  66. Scalar u1 = std::numeric_limits<Scalar>::infinity();
  67. Scalar u2 = 0;
  68. for(int i=0;i<3;i++)
  69. {
  70. d(i) = dist_to_B(V(i,0),V(i,1),V(i,2));
  71. // Lower bound is simply the max over vertex distances
  72. l = std::max(d(i),l);
  73. // u1 is the minimum of corner distances + maximum adjacent edge
  74. u1 = std::min(u1,d(i) + std::max(e((i+1)%3),e((i+2)%3)));
  75. // u2 first takes the maximum over corner distances
  76. u2 = std::max(u2,d(i));
  77. }
  78. // u2 is the distance from the circumcenter/midpoint of obtuse edge plus the
  79. // largest corner distance
  80. u2 += (s-r>2.*R ? R : 0.5*e_max);
  81. u = std::min(u1,u2);
  82. }
  83. #ifdef IGL_STATIC_LIBRARY
  84. template void igl::hausdorff<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, double&);
  85. template void igl::hausdorff<Eigen::Matrix<double, -1, -1, 0, -1, -1>, double>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, std::function<double (double const&, double const&, double const&)> const&, double&, double&);
  86. #endif