sort_vectors_ccw.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include <igl/sort_vectors_ccw.h>
  9. #include <igl/sort.h>
  10. #include <Eigen/Dense>
  11. template <typename DerivedS, typename DerivedI>
  12. IGL_INLINE void igl::sort_vectors_ccw(
  13. const Eigen::PlainObjectBase<DerivedS>& P,
  14. const Eigen::PlainObjectBase<DerivedS>& N,
  15. Eigen::PlainObjectBase<DerivedI> &order)
  16. {
  17. int half_degree = P.cols()/3;
  18. //local frame
  19. Eigen::Matrix<typename DerivedS::Scalar,1,3> e1 = P.head(3).normalized();
  20. Eigen::Matrix<typename DerivedS::Scalar,1,3> e3 = N.normalized();
  21. Eigen::Matrix<typename DerivedS::Scalar,1,3> e2 = e3.cross(e1);
  22. Eigen::Matrix<typename DerivedS::Scalar,3,3> F; F<<e1.transpose(),e2.transpose(),e3.transpose();
  23. Eigen::Matrix<typename DerivedS::Scalar,Eigen::Dynamic,1> angles(half_degree,1);
  24. for (int i=0; i<half_degree; ++i)
  25. {
  26. Eigen::Matrix<typename DerivedS::Scalar,1,3> Pl = F.colPivHouseholderQr().solve(P.segment(i*3,3).transpose()).transpose();
  27. // assert(fabs(Pl(2))/Pl.cwiseAbs().maxCoeff() <1e-5);
  28. angles[i] = atan2(Pl(1),Pl(0));
  29. }
  30. igl::sort( angles, 1, true, angles, order);
  31. //make sure that the first element is always at the top
  32. while (order[0] != 0)
  33. {
  34. //do a circshift
  35. int temp = order[0];
  36. for (int i =0; i< half_degree-1; ++i)
  37. order[i] = order[i+1];
  38. order(half_degree-1) = temp;
  39. }
  40. }
  41. template <typename DerivedS, typename DerivedI>
  42. IGL_INLINE void igl::sort_vectors_ccw(
  43. const Eigen::PlainObjectBase<DerivedS>& P,
  44. const Eigen::PlainObjectBase<DerivedS>& N,
  45. Eigen::PlainObjectBase<DerivedI> &order,
  46. Eigen::PlainObjectBase<DerivedS> &sorted)
  47. {
  48. int half_degree = P.cols()/3;
  49. igl::sort_vectors_ccw(P,N,order);
  50. sorted.resize(1,half_degree*3);
  51. for (int i=0; i<half_degree; ++i)
  52. sorted.segment(i*3,3) = P.segment(order[i]*3,3);
  53. }
  54. template <typename DerivedS, typename DerivedI>
  55. IGL_INLINE void igl::sort_vectors_ccw(
  56. const Eigen::PlainObjectBase<DerivedS>& P,
  57. const Eigen::PlainObjectBase<DerivedS>& N,
  58. Eigen::PlainObjectBase<DerivedI> &order,
  59. Eigen::PlainObjectBase<DerivedI> &inv_order)
  60. {
  61. int half_degree = P.cols()/3;
  62. igl::sort_vectors_ccw(P,N,order);
  63. inv_order.resize(half_degree,1);
  64. for (int i=0; i<half_degree; ++i)
  65. {
  66. for (int j=0; j<half_degree; ++j)
  67. if (order[j] ==i)
  68. {
  69. inv_order(i) = j;
  70. break;
  71. }
  72. }
  73. assert(inv_order[0] == 0);
  74. }
  75. template <typename DerivedS, typename DerivedI>
  76. IGL_INLINE void igl::sort_vectors_ccw(
  77. const Eigen::PlainObjectBase<DerivedS>& P,
  78. const Eigen::PlainObjectBase<DerivedS>& N,
  79. Eigen::PlainObjectBase<DerivedI> &order,
  80. Eigen::PlainObjectBase<DerivedS> &sorted,
  81. Eigen::PlainObjectBase<DerivedI> &inv_order)
  82. {
  83. int half_degree = P.cols()/3;
  84. igl::sort_vectors_ccw(P,N,order,inv_order);
  85. sorted.resize(1,half_degree*3);
  86. for (int i=0; i<half_degree; ++i)
  87. sorted.segment(i*3,3) = P.segment(order[i]*3,3);
  88. }
  89. #ifdef IGL_STATIC_LIBRARY
  90. // Explicit template instantiation
  91. 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> >&);
  92. 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> >&);
  93. #endif