half_space_box.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include "half_space_box.h"
  2. #include "assign_scalar.h"
  3. #include <CGAL/Point_3.h>
  4. #include <CGAL/Vector_3.h>
  5. template <typename DerivedV, typename Index>
  6. IGL_INLINE void igl::copyleft::cgal::half_space_box(
  7. const CGAL::Plane_3<CGAL::Epeck> & P,
  8. const Eigen::MatrixBase<DerivedV> & V,
  9. Eigen::Matrix<CGAL::Epeck::FT,8,3> & BV,
  10. Eigen::Matrix<Index,12,3> & BF)
  11. {
  12. typedef CGAL::Point_3<CGAL::Epeck> Point;
  13. typedef CGAL::Vector_3<CGAL::Epeck> Vector;
  14. typedef CGAL::Epeck::FT EScalar;
  15. Point o3(V(0,0),V(0,1),V(0,2));
  16. Point o2 = P.projection(o3);
  17. //https://math.stackexchange.com/a/4112622/35376
  18. const auto copysign = [](const EScalar & a, const EScalar & b)->EScalar
  19. {
  20. return (b>=0 ? abs(a) : -abs(a));
  21. };
  22. Vector n = P.orthogonal_vector();
  23. Vector u(
  24. copysign(n.z(),n.x()),
  25. copysign(n.z(),n.y()),
  26. -copysign(n.x(),n.z()) - copysign(n.y(),n.z()));
  27. // L1 of bounding box diagonal. ‖x‖₂ ≤ ‖x‖₁
  28. const EScalar bbd =
  29. (EScalar(V.col(0).maxCoeff())- EScalar(V.col(0).minCoeff())) +
  30. (EScalar(V.col(1).maxCoeff())- EScalar(V.col(1).minCoeff())) +
  31. (EScalar(V.col(2).maxCoeff())- EScalar(V.col(2).minCoeff()));
  32. const EScalar bbd_sqr = bbd*bbd;
  33. // now we have a center o2 and a vector u to the farthest point on the plane
  34. std::vector<Point> vBV;vBV.reserve(8);
  35. Vector v = CGAL::cross_product(u,n);
  36. // Scale u,v,n to be longer than bbd
  37. const auto & longer_than = [](const EScalar min_sqr, Vector & x)
  38. {
  39. assert(x.squared_length() > 0);
  40. while(x.squared_length() < min_sqr)
  41. {
  42. x = 2.*x;
  43. }
  44. };
  45. longer_than(bbd_sqr,u);
  46. longer_than(bbd_sqr,v);
  47. longer_than(bbd_sqr,n);
  48. vBV.emplace_back( o2 + u + v);
  49. vBV.emplace_back( o2 - u + v);
  50. vBV.emplace_back( o2 - u - v);
  51. vBV.emplace_back( o2 + u - v);
  52. vBV.emplace_back( o2 + u + v - n);
  53. vBV.emplace_back( o2 - u + v - n);
  54. vBV.emplace_back( o2 - u - v - n);
  55. vBV.emplace_back( o2 + u - v - n);
  56. BV.resize(8,3);
  57. for(int b = 0;b<8;b++)
  58. {
  59. igl::copyleft::cgal::assign_scalar(vBV[b].x(),BV(b,0));
  60. igl::copyleft::cgal::assign_scalar(vBV[b].y(),BV(b,1));
  61. igl::copyleft::cgal::assign_scalar(vBV[b].z(),BV(b,2));
  62. }
  63. BF.resize(12,3);
  64. BF<<
  65. 1,0,2,
  66. 2,0,3,
  67. 4,5,6,
  68. 4,6,7,
  69. 0,1,4,
  70. 4,1,5,
  71. 1,2,5,
  72. 5,2,6,
  73. 2,3,6,
  74. 6,3,7,
  75. 3,0,7,
  76. 7,0,4;
  77. }
  78. template <typename Derivedp, typename Derivedn, typename DerivedV, typename Index>
  79. IGL_INLINE void igl::copyleft::cgal::half_space_box(
  80. const Eigen::MatrixBase<Derivedp> & p,
  81. const Eigen::MatrixBase<Derivedn> & n,
  82. const Eigen::MatrixBase<DerivedV> & V,
  83. Eigen::Matrix<CGAL::Epeck::FT,8,3> & BV,
  84. Eigen::Matrix<Index,12,3> & BF)
  85. {
  86. typedef CGAL::Plane_3<CGAL::Epeck> Plane;
  87. typedef CGAL::Point_3<CGAL::Epeck> Point;
  88. typedef CGAL::Vector_3<CGAL::Epeck> Vector;
  89. Plane P(Point(p(0),p(1),p(2)),Vector(n(0),n(1),n(2)));
  90. return half_space_box(P,V,BV,BF);
  91. }
  92. template <typename Derivedequ, typename DerivedV, typename Index>
  93. IGL_INLINE void igl::copyleft::cgal::half_space_box(
  94. const Eigen::MatrixBase<Derivedequ> & equ,
  95. const Eigen::MatrixBase<DerivedV> & V,
  96. Eigen::Matrix<CGAL::Epeck::FT,8,3> & BV,
  97. Eigen::Matrix<Index,12,3> & BF)
  98. {
  99. typedef CGAL::Plane_3<CGAL::Epeck> Plane;
  100. Plane P(equ(0),equ(1),equ(2),equ(3));
  101. return half_space_box(P,V,BV,BF);
  102. }
  103. #ifdef IGL_STATIC_LIBRARY
  104. // Explicit template instantiation
  105. // generated by autoexplicit.sh
  106. template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<double, 1, 4, 1, 1, 4>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, int>(Eigen::MatrixBase<Eigen::Matrix<double, 1, 4, 1, 1, 4>> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
  107. template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<double, -1, 3, 1, -1, 3>, int>(CGAL::Plane_3<CGAL::Epeck> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
  108. // generated by autoexplicit.sh
  109. template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<float, -1, 3, 1, -1, 3>, int>(CGAL::Plane_3<CGAL::Epeck> const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
  110. template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4>, Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3>, int>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 3, 0, -1, 3> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
  111. template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4>, Eigen::Matrix<CGAL::Epeck::FT, -1, 4, 0, -1, 4>, int>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, 4, 0, -1, 4> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
  112. template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, int>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, 1, 4, 1, 1, 4> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
  113. template void igl::copyleft::cgal::half_space_box<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, int>(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<CGAL::Epeck::FT, 8, 3, 0, 8, 3>&, Eigen::Matrix<int, 12, 3, 0, 12, 3>&);
  114. #endif