voxel_grid.cpp 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. #include "voxel_grid.h"
  2. #include "grid.h"
  3. IGL_INLINE void igl::voxel_grid(
  4. const Eigen::AlignedBox3d & box,
  5. const int in_s,
  6. const int pad_count,
  7. Eigen::MatrixXd & GV,
  8. Eigen::RowVector3i & side)
  9. {
  10. using namespace Eigen;
  11. using namespace std;
  12. MatrixXd::Index si = -1;
  13. box.diagonal().maxCoeff(&si);
  14. //MatrixXd::Index si = 0;
  15. //assert(si>=0);
  16. const double s_len = box.diagonal()(si);
  17. assert(in_s>(pad_count*2+1) && "s should be > 2*pad_count+1");
  18. const double s = in_s - 2*pad_count;
  19. side(si) = s;
  20. for(int i = 0;i<3;i++)
  21. {
  22. if(i!=si)
  23. {
  24. side(i) = ceil(s * (box.max()(i)-box.min()(i))/s_len);
  25. }
  26. }
  27. side.array() += 2*pad_count;
  28. grid(side,GV);
  29. // A * p/s + B = min
  30. // A * (1-p/s) + B = max
  31. // B = min - A * p/s
  32. // A * (1-p/s) + min - A * p/s = max
  33. // A * (1-p/s) - A * p/s = max-min
  34. // A * (1-2p/s) = max-min
  35. // A = (max-min)/(1-2p/s)
  36. const Array<double,3,1> ps=
  37. (double)(pad_count)/(side.transpose().cast<double>().array()-1.);
  38. const Array<double,3,1> A = box.diagonal().array()/(1.0-2.*ps);
  39. //// This would result in an "anamorphic", but perfectly fit grid:
  40. //const Array<double,3,1> B = box.min().array() - A.array()*ps;
  41. //GV.array().rowwise() *= A.transpose();
  42. //GV.array().rowwise() += B.transpose();
  43. // Instead scale by largest factor and move to match center
  44. Array<double,3,1>::Index ai = -1;
  45. double a = A.maxCoeff(&ai);
  46. const Array<double,1,3> ratio =
  47. a*(side.cast<double>().array()-1.0)/(double)(side(ai)-1.0);
  48. GV.array().rowwise() *= ratio;
  49. GV.rowwise() += (box.center().transpose()-GV.colwise().mean()).eval();
  50. }