sort_vectors_ccw.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. const bool do_sorted,
  10. Eigen::PlainObjectBase<DerivedS> &sorted,
  11. const bool do_inv_order,
  12. Eigen::PlainObjectBase<DerivedI> &inv_order)
  13. {
  14. int half_degree = P.cols()/3;
  15. //local frame
  16. Eigen::Matrix<typename DerivedS::Scalar,1,3> e1 = P.head(3).normalized();
  17. Eigen::Matrix<typename DerivedS::Scalar,1,3> e3 = N.normalized();
  18. Eigen::Matrix<typename DerivedS::Scalar,1,3> e2 = e3.cross(e1);
  19. Eigen::Matrix<typename DerivedS::Scalar,3,3> F; F<<e1.transpose(),e2.transpose(),e3.transpose();
  20. Eigen::Matrix<typename DerivedS::Scalar,Eigen::Dynamic,1> angles(half_degree,1);
  21. for (int i=0; i<half_degree; ++i)
  22. {
  23. Eigen::Matrix<typename DerivedS::Scalar,1,3> Pl = F.colPivHouseholderQr().solve(P.segment(i*3,3).transpose()).transpose();
  24. assert(fabs(Pl(2))/Pl.cwiseAbs().maxCoeff() <1e-5);
  25. angles[i] = atan2(Pl(1),Pl(0));
  26. }
  27. igl::sort( angles, 1, true, angles, order);
  28. //make sure that the first element is always at the top
  29. while (order[0] != 0)
  30. {
  31. //do a circshift
  32. int temp = order[0];
  33. for (int i =0; i< half_degree-1; ++i)
  34. order[i] = order[i+1];
  35. order(half_degree-1) = temp;
  36. }
  37. if (do_sorted)
  38. {
  39. sorted.resize(1,half_degree*3);
  40. for (int i=0; i<half_degree; ++i)
  41. sorted.segment(i*3,3) = P.segment(order[i]*3,3);
  42. }
  43. if (do_inv_order)
  44. {
  45. inv_order.resize(half_degree,1);
  46. for (int i=0; i<half_degree; ++i)
  47. {
  48. for (int j=0; j<half_degree; ++j)
  49. if (order[j] ==i)
  50. {
  51. inv_order(i) = j;
  52. break;
  53. }
  54. }
  55. assert(inv_order[0] == 0);
  56. }
  57. }
  58. #ifdef IGL_STATIC_LIBRARY
  59. // Explicit template specialization
  60. 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> >&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> >&, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  61. #endif