sort_angles.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 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 "sort_angles.h"
  9. #include "LinSpaced.h"
  10. #include <algorithm>
  11. template <typename DerivedM, typename DerivedR>
  12. IGL_INLINE void igl::sort_angles(
  13. const Eigen::PlainObjectBase<DerivedM>& M,
  14. Eigen::PlainObjectBase<DerivedR>& R) {
  15. const size_t num_rows = M.rows();
  16. const size_t num_cols = M.cols();
  17. assert(num_cols >= 2);
  18. R.resize(num_rows);
  19. // Have to use << instead of = because Eigen's PlainObjectBase is annoying
  20. R << igl::LinSpaced<
  21. Eigen::Matrix<typename DerivedR::Scalar, Eigen::Dynamic, 1> >
  22. (num_rows, 0, num_rows-1);
  23. // |
  24. // (pi/2, pi) | (0, pi/2)
  25. // |
  26. // -------------+--------------
  27. // |
  28. // (-pi, -pi/2) | (-pi/2, 0)
  29. // |
  30. auto comp = [&](size_t i, size_t j) {
  31. auto yi = M(i, 0);
  32. auto xi = M(i, 1);
  33. auto yj = M(j, 0);
  34. auto xj = M(j, 1);
  35. if (xi == xj && yi == yj) {
  36. for (size_t idx=2; idx<num_cols; idx++) {
  37. auto i_val = M(i, idx);
  38. auto j_val = M(j, idx);
  39. if (i_val != j_val) {
  40. return i_val < j_val;
  41. }
  42. }
  43. // If the entire rows are equal, use the row index.
  44. return i < j;
  45. }
  46. if (xi >= 0 && yi >= 0) {
  47. if (xj >=0 && yj >= 0) {
  48. if (xi != xj) {
  49. return xi > xj;
  50. } else {
  51. return yi < yj;
  52. }
  53. } else if (xj < 0 && yj >= 0) {
  54. return true;
  55. } else if (xj < 0 && yj < 0) {
  56. return false;
  57. } else {
  58. return false;
  59. }
  60. } else if (xi < 0 && yi >= 0) {
  61. if (xj >= 0 && yj >= 0) {
  62. return false;
  63. } else if (xj < 0 && yj >= 0) {
  64. if (xi != xj) {
  65. return xi > xj;
  66. } else {
  67. return yi > yj;
  68. }
  69. } else if (xj < 0 && yj < 0) {
  70. return false;
  71. } else {
  72. return false;
  73. }
  74. } else if (xi < 0 && yi < 0) {
  75. if (xj >= 0 && yj >= 0) {
  76. return true;
  77. } else if (xj < 0 && yj >= 0) {
  78. return true;
  79. } else if (xj < 0 && yj < 0) {
  80. if (xi != xj) {
  81. return xi < xj;
  82. } else {
  83. return yi > yj;
  84. }
  85. } else {
  86. return true;
  87. }
  88. } else {
  89. if (xj >= 0 && yj >= 0) {
  90. return true;
  91. } else if (xj < 0 && yj >= 0) {
  92. return true;
  93. } else if (xj < 0 && yj < 0) {
  94. return false;
  95. } else {
  96. if (xi != xj) {
  97. return xi < xj;
  98. } else {
  99. return yi < yj;
  100. }
  101. }
  102. }
  103. };
  104. std::sort(R.data(), R.data() + num_rows, comp);
  105. }
  106. #ifdef IGL_STATIC_LIBRARY
  107. template void igl::sort_angles<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  108. #endif