]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 : | |
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> | |
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> | |
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> | |
69 | 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> | |
78 | inline bool same() const | |
79 | { | |
80 | return sides[Which].first * sides[Which].second == 1; | |
81 | } | |
82 | ||
83 | 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 | ||
91 | inline bool crossing() const | |
92 | { | |
93 | return sides[0].first * sides[0].second == -1 | |
94 | && sides[1].first * sides[1].second == -1; | |
95 | } | |
96 | ||
97 | 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> | |
106 | 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 | ||
114 | 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> | |
121 | inline bool zero() const | |
122 | { | |
123 | return sides[Which].first == 0 && sides[Which].second == 0; | |
124 | } | |
125 | ||
126 | template <int Which> | |
127 | 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 | ||
133 | 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> | |
144 | 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) | |
150 | 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 | ||
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 |