sort_vectors_ccw.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include <igl/sort_vectors_ccw.h>
  2. #include <igl/sort.h>
  3. #include <Eigen/Dense>
  4. template <typename DerivedS, typename DerivedI>
  5. IGL_INLINE void igl::sort_vectors_ccw(
  6. const Eigen::PlainObjectBase<DerivedS>& P,
  7. const Eigen::PlainObjectBase<DerivedS>& N,
  8. Eigen::PlainObjectBase<DerivedI> &order)
  9. {
  10. int half_degree = P.cols()/3;
  11. //local frame
  12. Eigen::Matrix<typename DerivedS::Scalar,1,3> e1 = P.head(3).normalized();
  13. Eigen::Matrix<typename DerivedS::Scalar,1,3> e3 = N.normalized();
  14. Eigen::Matrix<typename DerivedS::Scalar,1,3> e2 = e3.cross(e1);
  15. Eigen::Matrix<typename DerivedS::Scalar,3,3> F; F<<e1.transpose(),e2.transpose(),e3.transpose();
  16. Eigen::Matrix<typename DerivedS::Scalar,Eigen::Dynamic,1> angles(half_degree,1);
  17. for (int i=0; i<half_degree; ++i)
  18. {
  19. Eigen::Matrix<typename DerivedS::Scalar,1,3> Pl = F.colPivHouseholderQr().solve(P.segment(i*3,3).transpose()).transpose();
  20. // assert(fabs(Pl(2))/Pl.cwiseAbs().maxCoeff() <1e-5);
  21. angles[i] = atan2(Pl(1),Pl(0));
  22. }
  23. igl::sort( angles, 1, true, angles, order);
  24. //make sure that the first element is always at the top
  25. while (order[0] != 0)
  26. {
  27. //do a circshift
  28. int temp = order[0];
  29. for (int i =0; i< half_degree-1; ++i)
  30. order[i] = order[i+1];
  31. order(half_degree-1) = temp;
  32. }
  33. }
  34. template <typename DerivedS, typename DerivedI>
  35. IGL_INLINE void igl::sort_vectors_ccw(
  36. const Eigen::PlainObjectBase<DerivedS>& P,
  37. const Eigen::PlainObjectBase<DerivedS>& N,
  38. Eigen::PlainObjectBase<DerivedI> &order,
  39. Eigen::PlainObjectBase<DerivedS> &sorted)
  40. {
  41. int half_degree = P.cols()/3;
  42. igl::sort_vectors_ccw(P,N,order);
  43. sorted.resize(1,half_degree*3);
  44. for (int i=0; i<half_degree; ++i)
  45. sorted.segment(i*3,3) = P.segment(order[i]*3,3);
  46. }
  47. template <typename DerivedS, typename DerivedI>
  48. IGL_INLINE void igl::sort_vectors_ccw(
  49. const Eigen::PlainObjectBase<DerivedS>& P,
  50. const Eigen::PlainObjectBase<DerivedS>& N,
  51. Eigen::PlainObjectBase<DerivedI> &order,
  52. Eigen::PlainObjectBase<DerivedI> &inv_order)
  53. {
  54. int half_degree = P.cols()/3;
  55. igl::sort_vectors_ccw(P,N,order);
  56. inv_order.resize(half_degree,1);
  57. for (int i=0; i<half_degree; ++i)
  58. {
  59. for (int j=0; j<half_degree; ++j)
  60. if (order[j] ==i)
  61. {
  62. inv_order(i) = j;
  63. break;
  64. }
  65. }
  66. assert(inv_order[0] == 0);
  67. }
  68. template <typename DerivedS, typename DerivedI>
  69. IGL_INLINE void igl::sort_vectors_ccw(
  70. const Eigen::PlainObjectBase<DerivedS>& P,
  71. const Eigen::PlainObjectBase<DerivedS>& N,
  72. Eigen::PlainObjectBase<DerivedI> &order,
  73. Eigen::PlainObjectBase<DerivedS> &sorted,
  74. Eigen::PlainObjectBase<DerivedI> &inv_order)
  75. {
  76. int half_degree = P.cols()/3;
  77. igl::sort_vectors_ccw(P,N,order,inv_order);
  78. sorted.resize(1,half_degree*3);
  79. for (int i=0; i<half_degree; ++i)
  80. sorted.segment(i*3,3) = P.segment(order[i]*3,3);
  81. }
  82. #ifdef IGL_STATIC_LIBRARY
  83. // Explicit template specialization
  84. template void igl::sort_vectors_ccw<Eigen::Matrix<double, 1, -1, 1, 1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  85. template void igl::sort_vectors_ccw<Eigen::Matrix<double, 1, -1, 1, 1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> >&);
  86. #endif