]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/include/boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / algorithms / detail / overlay / get_turn_info_helpers.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4
5// This file was modified by Oracle on 2013, 2014, 2015.
6// Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
7
8// Use, modification and distribution is subject to the Boost Software License,
9// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10// http://www.boost.org/LICENSE_1_0.txt)
11
12// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
13
14#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
15#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
16
17#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
18
19namespace boost { namespace geometry {
20
21#ifndef DOXYGEN_NO_DETAIL
22namespace detail { namespace overlay {
23
24enum turn_position { position_middle, position_front, position_back };
25
26template <typename Point, typename SegmentRatio>
27struct turn_operation_linear
28 : public turn_operation<Point, SegmentRatio>
29{
30 turn_operation_linear()
31 : position(position_middle)
32 , is_collinear(false)
33 {}
34
35 turn_position position;
36 bool is_collinear; // valid only for Linear geometry
37};
38
39template <typename TurnPointCSTag, typename PointP, typename PointQ,
40 typename Pi = PointP, typename Pj = PointP, typename Pk = PointP,
41 typename Qi = PointQ, typename Qj = PointQ, typename Qk = PointQ
42>
43struct side_calculator
44{
45 // This strategy should be the same as side strategy defined in
46 // intersection_strategies<> which is used in various places
47 // of the library
48 typedef typename strategy::side::services::default_strategy
49 <
50 TurnPointCSTag
51 >::type side;
52
53 inline side_calculator(Pi const& pi, Pj const& pj, Pk const& pk,
54 Qi const& qi, Qj const& qj, Qk const& qk)
55 : m_pi(pi), m_pj(pj), m_pk(pk)
56 , m_qi(qi), m_qj(qj), m_qk(qk)
57 {}
58
59 inline int pk_wrt_p1() const { return side::apply(m_pi, m_pj, m_pk); }
60 inline int pk_wrt_q1() const { return side::apply(m_qi, m_qj, m_pk); }
61 inline int qk_wrt_p1() const { return side::apply(m_pi, m_pj, m_qk); }
62 inline int qk_wrt_q1() const { return side::apply(m_qi, m_qj, m_qk); }
63
64 inline int pk_wrt_q2() const { return side::apply(m_qj, m_qk, m_pk); }
65 inline int qk_wrt_p2() const { return side::apply(m_pj, m_pk, m_qk); }
66
67 Pi const& m_pi;
68 Pj const& m_pj;
69 Pk const& m_pk;
70 Qi const& m_qi;
71 Qj const& m_qj;
72 Qk const& m_qk;
73};
74
75template <typename Point1, typename Point2, typename RobustPolicy>
76struct robust_points
77{
78 typedef typename geometry::robust_point_type
79 <
80 Point1, RobustPolicy
81 >::type robust_point1_type;
82
83 // TODO: define robust_point2_type using Point2?
84 typedef robust_point1_type robust_point2_type;
85
86 inline robust_points(Point1 const& pi, Point1 const& pj, Point1 const& pk,
87 Point2 const& qi, Point2 const& qj, Point2 const& qk,
88 RobustPolicy const& robust_policy)
89 {
90 geometry::recalculate(m_rpi, pi, robust_policy);
91 geometry::recalculate(m_rpj, pj, robust_policy);
92 geometry::recalculate(m_rpk, pk, robust_policy);
93 geometry::recalculate(m_rqi, qi, robust_policy);
94 geometry::recalculate(m_rqj, qj, robust_policy);
95 geometry::recalculate(m_rqk, qk, robust_policy);
96 }
97
98 robust_point1_type m_rpi, m_rpj, m_rpk;
99 robust_point2_type m_rqi, m_rqj, m_rqk;
100};
101
102template <typename Point1, typename Point2, typename TurnPoint, typename RobustPolicy>
103class intersection_info_base
104 : private robust_points<Point1, Point2, RobustPolicy>
105{
106 typedef robust_points<Point1, Point2, RobustPolicy> base;
107
108public:
109 typedef Point1 point1_type;
110 typedef Point2 point2_type;
111
112 typedef typename base::robust_point1_type robust_point1_type;
113 typedef typename base::robust_point2_type robust_point2_type;
114
115 typedef typename cs_tag<TurnPoint>::type cs_tag;
116
117 typedef side_calculator<cs_tag, robust_point1_type, robust_point2_type> side_calculator_type;
118
119 intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk,
120 Point2 const& qi, Point2 const& qj, Point2 const& qk,
121 RobustPolicy const& robust_policy)
122 : base(pi, pj, pk, qi, qj, qk, robust_policy)
123 , m_side_calc(base::m_rpi, base::m_rpj, base::m_rpk,
124 base::m_rqi, base::m_rqj, base::m_rqk)
125 , m_pi(pi), m_pj(pj), m_pk(pk)
126 , m_qi(qi), m_qj(qj), m_qk(qk)
127 {}
128
129 inline Point1 const& pi() const { return m_pi; }
130 inline Point1 const& pj() const { return m_pj; }
131 inline Point1 const& pk() const { return m_pk; }
132
133 inline Point2 const& qi() const { return m_qi; }
134 inline Point2 const& qj() const { return m_qj; }
135 inline Point2 const& qk() const { return m_qk; }
136
137 inline robust_point1_type const& rpi() const { return base::m_rpi; }
138 inline robust_point1_type const& rpj() const { return base::m_rpj; }
139 inline robust_point1_type const& rpk() const { return base::m_rpk; }
140
141 inline robust_point2_type const& rqi() const { return base::m_rqi; }
142 inline robust_point2_type const& rqj() const { return base::m_rqj; }
143 inline robust_point2_type const& rqk() const { return base::m_rqk; }
144
145 inline side_calculator_type const& sides() const { return m_side_calc; }
146
147private:
148 side_calculator_type m_side_calc;
149
150 point1_type const& m_pi;
151 point1_type const& m_pj;
152 point1_type const& m_pk;
153 point2_type const& m_qi;
154 point2_type const& m_qj;
155 point2_type const& m_qk;
156};
157
158template <typename Point1, typename Point2, typename TurnPoint>
159class intersection_info_base<Point1, Point2, TurnPoint, detail::no_rescale_policy>
160{
161public:
162 typedef Point1 point1_type;
163 typedef Point2 point2_type;
164
165 typedef Point1 robust_point1_type;
166 typedef Point2 robust_point2_type;
167
168 typedef typename cs_tag<TurnPoint>::type cs_tag;
169
170 typedef side_calculator<cs_tag, Point1, Point2> side_calculator_type;
171
172 intersection_info_base(Point1 const& pi, Point1 const& pj, Point1 const& pk,
173 Point2 const& qi, Point2 const& qj, Point2 const& qk,
174 no_rescale_policy const& /*robust_policy*/)
175 : m_side_calc(pi, pj, pk, qi, qj, qk)
176 {}
177
178 inline Point1 const& pi() const { return m_side_calc.m_pi; }
179 inline Point1 const& pj() const { return m_side_calc.m_pj; }
180 inline Point1 const& pk() const { return m_side_calc.m_pk; }
181
182 inline Point2 const& qi() const { return m_side_calc.m_qi; }
183 inline Point2 const& qj() const { return m_side_calc.m_qj; }
184 inline Point2 const& qk() const { return m_side_calc.m_qk; }
185
186 inline Point1 const& rpi() const { return pi(); }
187 inline Point1 const& rpj() const { return pj(); }
188 inline Point1 const& rpk() const { return pk(); }
189
190 inline Point2 const& rqi() const { return qi(); }
191 inline Point2 const& rqj() const { return qj(); }
192 inline Point2 const& rqk() const { return qk(); }
193
194 inline side_calculator_type const& sides() const { return m_side_calc; }
195
196private:
197 side_calculator_type m_side_calc;
198};
199
200
201template
202<
203 typename Point1,
204 typename Point2,
205 typename TurnPoint,
206 typename RobustPolicy
207>
208class intersection_info
209 : public intersection_info_base<Point1, Point2, TurnPoint, RobustPolicy>
210{
211 typedef intersection_info_base<Point1, Point2, TurnPoint, RobustPolicy> base;
212
213 typedef typename intersection_strategies
214 <
215 typename base::cs_tag,
216 Point1,
217 Point2,
218 TurnPoint,
219 RobustPolicy
220 >::segment_intersection_strategy_type strategy;
221
222public:
223 typedef model::referring_segment<Point1 const> segment_type1;
224 typedef model::referring_segment<Point2 const> segment_type2;
225 typedef typename base::side_calculator_type side_calculator_type;
226
227 typedef typename strategy::return_type result_type;
228 typedef typename boost::tuples::element<0, result_type>::type i_info_type; // intersection_info
229 typedef typename boost::tuples::element<1, result_type>::type d_info_type; // dir_info
230
231 intersection_info(Point1 const& pi, Point1 const& pj, Point1 const& pk,
232 Point2 const& qi, Point2 const& qj, Point2 const& qk,
233 RobustPolicy const& robust_policy)
234 : base(pi, pj, pk, qi, qj, qk, robust_policy)
235 , m_result(strategy::apply(segment_type1(pi, pj),
236 segment_type2(qi, qj),
237 robust_policy,
238 base::rpi(), base::rpj(),
239 base::rqi(), base::rqj()))
240 , m_robust_policy(robust_policy)
241 {}
242
243 inline result_type const& result() const { return m_result; }
244 inline i_info_type const& i_info() const { return m_result.template get<0>(); }
245 inline d_info_type const& d_info() const { return m_result.template get<1>(); }
246
247 // TODO: it's more like is_spike_ip_p
248 inline bool is_spike_p() const
249 {
250 if (base::sides().pk_wrt_p1() == 0)
251 {
252 if (! is_ip_j<0>())
253 {
254 return false;
255 }
256
257 int const qk_p1 = base::sides().qk_wrt_p1();
258 int const qk_p2 = base::sides().qk_wrt_p2();
259
260 if (qk_p1 == -qk_p2)
261 {
262 if (qk_p1 == 0)
263 {
264 return is_spike_of_collinear(base::pi(), base::pj(),
265 base::pk());
266 }
267
268 return true;
269 }
270 }
271
272 return false;
273 }
274
275 // TODO: it's more like is_spike_ip_q
276 inline bool is_spike_q() const
277 {
278 if (base::sides().qk_wrt_q1() == 0)
279 {
280 if (! is_ip_j<1>())
281 {
282 return false;
283 }
284
285 int const pk_q1 = base::sides().pk_wrt_q1();
286 int const pk_q2 = base::sides().pk_wrt_q2();
287
288 if (pk_q1 == -pk_q2)
289 {
290 if (pk_q1 == 0)
291 {
292 return is_spike_of_collinear(base::qi(), base::qj(),
293 base::qk());
294 }
295
296 return true;
297 }
298 }
299
300 return false;
301 }
302
303private:
304 template <typename Point>
305 inline bool is_spike_of_collinear(Point const& i, Point const& j,
306 Point const& k) const
307 {
308 typedef model::referring_segment<Point const> seg;
309
310 typedef intersection_strategies
311 <
312 typename base::cs_tag, Point, Point, Point, RobustPolicy
313 > si;
314
315 typedef typename si::segment_intersection_strategy_type strategy;
316
317 typename strategy::return_type result
318 = strategy::apply(seg(i, j), seg(j, k), m_robust_policy);
319
320 return result.template get<0>().count == 2;
321 }
322
323 template <std::size_t OpId>
324 bool is_ip_j() const
325 {
326 int arrival = d_info().arrival[OpId];
327 bool same_dirs = d_info().dir_a == 0 && d_info().dir_b == 0;
328
329 if (same_dirs)
330 {
331 if (i_info().count == 2)
332 {
333 return arrival != -1;
334 }
335 else
336 {
337 return arrival == 0;
338 }
339 }
340 else
341 {
342 return arrival == 1;
343 }
344 }
345
346 result_type m_result;
347 RobustPolicy const& m_robust_policy;
348};
349
350}} // namespace detail::overlay
351#endif // DOXYGEN_NO_DETAIL
352
353}} // namespace boost::geometry
354
355#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP