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