You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

math.cpp 2.7 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include "geo/private/math/math.h"
  2. #include "geo/private/math/angle.h"
  3. namespace ns
  4. {
  5. namespace geo
  6. {
  7. namespace
  8. {
  9. constexpr auto epsilon = 1e-8;
  10. constexpr auto fairly_epsilon = 0.01; // 1cm. Heuristic
  11. constexpr auto angle_epsilon = c_pi() / 180.0; // 1⁰. Heuristic
  12. enum class EpsilonType
  13. {
  14. Normal,
  15. Fair,
  16. Angle
  17. };
  18. template <EpsilonType>
  19. struct EpsilonTraits;
  20. template <>
  21. struct EpsilonTraits<EpsilonType::Normal>
  22. {
  23. static constexpr auto value = epsilon;
  24. };
  25. template <>
  26. struct EpsilonTraits<EpsilonType::Fair>
  27. {
  28. static constexpr auto value = fairly_epsilon;
  29. };
  30. template <>
  31. struct EpsilonTraits<EpsilonType::Angle>
  32. {
  33. static constexpr auto value = angle_epsilon;
  34. };
  35. template <EpsilonType Type>
  36. bool are_equal(const double value1, const double value2)
  37. {
  38. const auto abs_diff = std::abs(value1 - value2);
  39. return abs_diff <= EpsilonTraits<Type>::value;
  40. }
  41. } // namespace
  42. bool are_fairly_equal(const double value1, const double value2)
  43. {
  44. return are_equal<EpsilonType::Fair>(value1, value2);
  45. }
  46. bool are_equal(const double value1, const double value2)
  47. {
  48. return are_equal<EpsilonType::Normal>(value1, value2);
  49. }
  50. bool is_zero(const double value)
  51. {
  52. return std::fpclassify(value) == FP_ZERO;
  53. }
  54. int32_t JudgeSideness(const PointD& p1, const PointD& p2, const PointD& p)
  55. {
  56. PointD v1(p2.x - p1.x, p2.y - p1.y);
  57. PointD v2(p.x - p1.x, p.y - p1.y);
  58. double value = v1.x * v2.y - v2.x * v1.y;
  59. if (value > 0)
  60. return 1;
  61. else if (value < 0)
  62. return -1;
  63. else
  64. return 0;
  65. }
  66. double vectorAngleDiff(const PointD& p1, const PointD& p2, const PointD& q1, const PointD& q2)
  67. {
  68. double angle1 = cal_east_angle(p1, p2);
  69. double angle2 = cal_east_angle(q1, q2);
  70. return diff_angle(angle1, angle2);
  71. }
  72. double linearDis2Begin(double sValue, double eValue, double length, double mValue)
  73. {
  74. if (sValue < eValue)
  75. {
  76. if (mValue < sValue)
  77. return 0;
  78. else if (mValue > eValue)
  79. return length;
  80. else
  81. return length * (mValue - sValue) / (eValue - sValue);
  82. }
  83. else if (sValue > eValue)
  84. {
  85. if (mValue < eValue)
  86. return 0;
  87. else if (mValue > sValue)
  88. return length;
  89. else
  90. return length * (mValue - sValue) / (eValue - sValue);
  91. }
  92. else
  93. {
  94. return -1;
  95. }
  96. }
  97. double linearValueAtS(double sValue, double eValue, double length, double s)
  98. {
  99. if (is_zero(length) || is_zero(s) || are_equal(sValue, eValue))
  100. {
  101. return sValue;
  102. }
  103. else
  104. {
  105. return s / length * (eValue - sValue) + sValue;
  106. }
  107. }
  108. } // namespace geo
  109. } // namespace ns