side_info.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  6. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  7. // Use, modification and distribution is subject to the Boost Software License,
  8. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_GEOMETRY_STRATEGIES_SIDE_INFO_HPP
  11. #define BOOST_GEOMETRY_STRATEGIES_SIDE_INFO_HPP
  12. #include <cmath>
  13. #include <utility>
  14. #if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) || defined(BOOST_GEOMETRY_DEBUG_ROBUSTNESS)
  15. # include <iostream>
  16. #endif
  17. namespace boost { namespace geometry
  18. {
  19. // Silence warning C4127: conditional expression is constant
  20. #if defined(_MSC_VER)
  21. #pragma warning(push)
  22. #pragma warning(disable : 4127)
  23. #endif
  24. /*!
  25. \brief Class side_info: small class wrapping for sides (-1,0,1)
  26. */
  27. class side_info
  28. {
  29. public :
  30. inline side_info(int side_a1 = 0, int side_a2 = 0,
  31. int side_b1 = 0, int side_b2 = 0)
  32. {
  33. sides[0].first = side_a1;
  34. sides[0].second = side_a2;
  35. sides[1].first = side_b1;
  36. sides[1].second = side_b2;
  37. }
  38. template <int Which>
  39. inline void set(int first, int second)
  40. {
  41. sides[Which].first = first;
  42. sides[Which].second = second;
  43. }
  44. template <int Which, int Index>
  45. inline void correct_to_zero()
  46. {
  47. if (Index == 0)
  48. {
  49. sides[Which].first = 0;
  50. }
  51. else
  52. {
  53. sides[Which].second = 0;
  54. }
  55. }
  56. template <int Which, int Index>
  57. inline int get() const
  58. {
  59. return Index == 0 ? sides[Which].first : sides[Which].second;
  60. }
  61. // Returns true if both lying on the same side WRT the other
  62. // (so either 1,1 or -1-1)
  63. template <int Which>
  64. inline bool same() const
  65. {
  66. return sides[Which].first * sides[Which].second == 1;
  67. }
  68. inline bool collinear() const
  69. {
  70. return sides[0].first == 0
  71. && sides[0].second == 0
  72. && sides[1].first == 0
  73. && sides[1].second == 0;
  74. }
  75. inline bool crossing() const
  76. {
  77. return sides[0].first * sides[0].second == -1
  78. && sides[1].first * sides[1].second == -1;
  79. }
  80. inline bool touching() const
  81. {
  82. return (sides[0].first * sides[1].first == -1
  83. && sides[0].second == 0 && sides[1].second == 0)
  84. || (sides[1].first * sides[0].first == -1
  85. && sides[1].second == 0 && sides[0].second == 0);
  86. }
  87. template <int Which>
  88. inline bool one_touching() const
  89. {
  90. // This is normally a situation which can't occur:
  91. // If one is completely left or right, the other cannot touch
  92. return one_zero<Which>()
  93. && sides[1 - Which].first * sides[1 - Which].second == 1;
  94. }
  95. inline bool meeting() const
  96. {
  97. // Two of them (in each segment) zero, two not
  98. return one_zero<0>() && one_zero<1>();
  99. }
  100. template <int Which>
  101. inline bool zero() const
  102. {
  103. return sides[Which].first == 0 && sides[Which].second == 0;
  104. }
  105. template <int Which>
  106. inline bool one_zero() const
  107. {
  108. return (sides[Which].first == 0 && sides[Which].second != 0)
  109. || (sides[Which].first != 0 && sides[Which].second == 0);
  110. }
  111. inline bool one_of_all_zero() const
  112. {
  113. int const sum = std::abs(sides[0].first)
  114. + std::abs(sides[0].second)
  115. + std::abs(sides[1].first)
  116. + std::abs(sides[1].second);
  117. return sum == 3;
  118. }
  119. template <int Which>
  120. inline int zero_index() const
  121. {
  122. return sides[Which].first == 0 ? 0 : 1;
  123. }
  124. #if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) || defined(BOOST_GEOMETRY_DEBUG_ROBUSTNESS)
  125. inline void debug() const
  126. {
  127. std::cout << sides[0].first << " "
  128. << sides[0].second << " "
  129. << sides[1].first << " "
  130. << sides[1].second
  131. << std::endl;
  132. }
  133. #endif
  134. inline void reverse()
  135. {
  136. std::swap(sides[0], sides[1]);
  137. }
  138. //private :
  139. std::pair<int, int> sides[2];
  140. };
  141. #if defined(_MSC_VER)
  142. #pragma warning(pop)
  143. #endif
  144. }} // namespace boost::geometry
  145. #endif // BOOST_GEOMETRY_STRATEGIES_SIDE_INFO_HPP