ramer_douglas_peucker.cpp 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #include "ramer_douglas_peucker.h"
  2. #include "find.h"
  3. #include "project_to_line.h"
  4. #include "EPS.h"
  5. #include "slice_mask.h"
  6. template <typename DerivedP, typename DerivedS, typename DerivedJ>
  7. IGL_INLINE void igl::ramer_douglas_peucker(
  8. const Eigen::MatrixBase<DerivedP> & P,
  9. const typename DerivedP::Scalar tol,
  10. Eigen::PlainObjectBase<DerivedS> & S,
  11. Eigen::PlainObjectBase<DerivedJ> & J)
  12. {
  13. typedef typename DerivedP::Scalar Scalar;
  14. // number of vertices
  15. const int n = P.rows();
  16. // Trivial base case
  17. if(n <= 1)
  18. {
  19. J = DerivedJ::Zero(n);
  20. S = P;
  21. return;
  22. }
  23. // number of dimensions
  24. const int m = P.cols();
  25. Eigen::Array<bool,Eigen::Dynamic,1> I =
  26. Eigen::Array<bool,Eigen::Dynamic,1>::Constant(n,1,true);
  27. const auto stol = tol*tol;
  28. std::function<void(const int,const int)> simplify;
  29. simplify = [&I,&P,&stol,&simplify](const int ixs, const int ixe)->void
  30. {
  31. assert(ixe>ixs);
  32. Scalar sdmax = 0;
  33. typename Eigen::Matrix<Scalar,Eigen::Dynamic,1>::Index ixc = -1;
  34. if((ixe-ixs)>1)
  35. {
  36. Scalar sdes = (P.row(ixe)-P.row(ixs)).squaredNorm();
  37. Eigen::Matrix<Scalar,Eigen::Dynamic,1> sD;
  38. const auto & Pblock = P.block(ixs+1,0,((ixe+1)-ixs)-2,P.cols());
  39. if(sdes<=EPS<Scalar>())
  40. {
  41. sD = (Pblock.rowwise()-P.row(ixs)).rowwise().squaredNorm();
  42. }else
  43. {
  44. Eigen::Matrix<Scalar,Eigen::Dynamic,1> T;
  45. project_to_line(Pblock,P.row(ixs).eval(),P.row(ixe).eval(),T,sD);
  46. }
  47. sdmax = sD.maxCoeff(&ixc);
  48. // Index full P
  49. ixc = ixc+(ixs+1);
  50. }
  51. if(sdmax <= stol)
  52. {
  53. if(ixs != ixe-1)
  54. {
  55. I.block(ixs+1,0,((ixe+1)-ixs)-2,1).setConstant(false);
  56. }
  57. }else
  58. {
  59. simplify(ixs,ixc);
  60. simplify(ixc,ixe);
  61. }
  62. };
  63. simplify(0,n-1);
  64. slice_mask(P,I,1,S);
  65. find(I,J);
  66. }