annotate DEPENDENCIES/generic/include/boost/geometry/algorithms/detail/relate/turns.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 // Boost.Geometry (aka GGL, Generic Geometry Library)
Chris@102 2
Chris@102 3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
Chris@102 4
Chris@102 5 // This file was modified by Oracle on 2013, 2014, 2015.
Chris@102 6 // Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
Chris@102 7
Chris@102 8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
Chris@102 9 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
Chris@102 10
Chris@102 11 // Use, modification and distribution is subject to the Boost Software License,
Chris@102 12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@102 13 // http://www.boost.org/LICENSE_1_0.txt)
Chris@102 14
Chris@102 15 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_TURNS_HPP
Chris@102 16 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_TURNS_HPP
Chris@102 17
Chris@102 18 #include <boost/geometry/strategies/distance.hpp>
Chris@102 19 #include <boost/geometry/algorithms/detail/overlay/do_reverse.hpp>
Chris@102 20 #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
Chris@102 21 #include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
Chris@102 22
Chris@102 23 #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
Chris@102 24 #include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
Chris@102 25
Chris@102 26 #include <boost/type_traits/is_base_of.hpp>
Chris@102 27
Chris@102 28
Chris@102 29 namespace boost { namespace geometry {
Chris@102 30
Chris@102 31 #ifndef DOXYGEN_NO_DETAIL
Chris@102 32 namespace detail { namespace relate { namespace turns {
Chris@102 33
Chris@102 34 template <bool IncludeDegenerate = false>
Chris@102 35 struct assign_policy
Chris@102 36 : overlay::assign_null_policy
Chris@102 37 {
Chris@102 38 static bool const include_degenerate = IncludeDegenerate;
Chris@102 39 };
Chris@102 40
Chris@102 41 // GET_TURNS
Chris@102 42
Chris@102 43 template
Chris@102 44 <
Chris@102 45 typename Geometry1,
Chris@102 46 typename Geometry2,
Chris@102 47 typename GetTurnPolicy = detail::get_turns::get_turn_info_type
Chris@102 48 <
Chris@102 49 Geometry1, Geometry2, assign_policy<>
Chris@102 50 >,
Chris@102 51 typename RobustPolicy = detail::no_rescale_policy
Chris@102 52 >
Chris@102 53 struct get_turns
Chris@102 54 {
Chris@102 55 typedef typename geometry::point_type<Geometry1>::type point1_type;
Chris@102 56
Chris@102 57 typedef overlay::turn_info
Chris@102 58 <
Chris@102 59 point1_type,
Chris@102 60 typename segment_ratio_type<point1_type, RobustPolicy>::type,
Chris@102 61 typename detail::get_turns::turn_operation_type
Chris@102 62 <
Chris@102 63 Geometry1, Geometry2,
Chris@102 64 typename segment_ratio_type
Chris@102 65 <
Chris@102 66 point1_type, RobustPolicy
Chris@102 67 >::type
Chris@102 68 >::type
Chris@102 69 > turn_info;
Chris@102 70
Chris@102 71 template <typename Turns>
Chris@102 72 static inline void apply(Turns & turns,
Chris@102 73 Geometry1 const& geometry1,
Chris@102 74 Geometry2 const& geometry2)
Chris@102 75 {
Chris@102 76 detail::get_turns::no_interrupt_policy interrupt_policy;
Chris@102 77
Chris@102 78 apply(turns, geometry1, geometry2, interrupt_policy);
Chris@102 79 }
Chris@102 80
Chris@102 81 template <typename Turns, typename InterruptPolicy>
Chris@102 82 static inline void apply(Turns & turns,
Chris@102 83 Geometry1 const& geometry1,
Chris@102 84 Geometry2 const& geometry2,
Chris@102 85 InterruptPolicy & interrupt_policy)
Chris@102 86 {
Chris@102 87 static const bool reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value;
Chris@102 88 static const bool reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value;
Chris@102 89
Chris@102 90 RobustPolicy robust_policy = geometry::get_rescale_policy
Chris@102 91 <
Chris@102 92 RobustPolicy
Chris@102 93 >(geometry1, geometry2);
Chris@102 94
Chris@102 95
Chris@102 96 dispatch::get_turns
Chris@102 97 <
Chris@102 98 typename geometry::tag<Geometry1>::type,
Chris@102 99 typename geometry::tag<Geometry2>::type,
Chris@102 100 Geometry1,
Chris@102 101 Geometry2,
Chris@102 102 reverse1,
Chris@102 103 reverse2,
Chris@102 104 GetTurnPolicy
Chris@102 105 >::apply(0, geometry1, 1, geometry2,
Chris@102 106 robust_policy, turns, interrupt_policy);
Chris@102 107 }
Chris@102 108 };
Chris@102 109
Chris@102 110 // TURNS SORTING AND SEARCHING
Chris@102 111
Chris@102 112 template <int N = 0, int U = 1, int I = 2, int B = 3, int C = 4, int O = 0>
Chris@102 113 struct op_to_int
Chris@102 114 {
Chris@102 115 template <typename SegmentRatio>
Chris@102 116 inline int operator()(detail::overlay::turn_operation<SegmentRatio> const& op) const
Chris@102 117 {
Chris@102 118 switch(op.operation)
Chris@102 119 {
Chris@102 120 case detail::overlay::operation_none : return N;
Chris@102 121 case detail::overlay::operation_union : return U;
Chris@102 122 case detail::overlay::operation_intersection : return I;
Chris@102 123 case detail::overlay::operation_blocked : return B;
Chris@102 124 case detail::overlay::operation_continue : return C;
Chris@102 125 case detail::overlay::operation_opposite : return O;
Chris@102 126 }
Chris@102 127 return -1;
Chris@102 128 }
Chris@102 129 };
Chris@102 130
Chris@102 131 template <std::size_t OpId, typename OpToInt>
Chris@102 132 struct less_op_xxx_linear
Chris@102 133 {
Chris@102 134 template <typename Turn>
Chris@102 135 inline bool operator()(Turn const& left, Turn const& right) const
Chris@102 136 {
Chris@102 137 static OpToInt op_to_int;
Chris@102 138 return op_to_int(left.operations[OpId]) < op_to_int(right.operations[OpId]);
Chris@102 139 }
Chris@102 140 };
Chris@102 141
Chris@102 142 template <std::size_t OpId>
Chris@102 143 struct less_op_linear_linear
Chris@102 144 : less_op_xxx_linear< OpId, op_to_int<0,2,3,1,4,0> >
Chris@102 145 {};
Chris@102 146
Chris@102 147 template <std::size_t OpId>
Chris@102 148 struct less_op_linear_areal_single
Chris@102 149 {
Chris@102 150 template <typename Turn>
Chris@102 151 inline bool operator()(Turn const& left, Turn const& right) const
Chris@102 152 {
Chris@102 153 static const std::size_t other_op_id = (OpId + 1) % 2;
Chris@102 154 static turns::op_to_int<0,2,3,1,4,0> op_to_int_xuic;
Chris@102 155 static turns::op_to_int<0,3,2,1,4,0> op_to_int_xiuc;
Chris@102 156
Chris@102 157 segment_identifier const& left_other_seg_id = left.operations[other_op_id].seg_id;
Chris@102 158 segment_identifier const& right_other_seg_id = right.operations[other_op_id].seg_id;
Chris@102 159
Chris@102 160 typedef typename Turn::turn_operation_type operation_type;
Chris@102 161 operation_type const& left_operation = left.operations[OpId];
Chris@102 162 operation_type const& right_operation = right.operations[OpId];
Chris@102 163
Chris@102 164 if ( left_other_seg_id.ring_index == right_other_seg_id.ring_index )
Chris@102 165 {
Chris@102 166 return op_to_int_xuic(left_operation)
Chris@102 167 < op_to_int_xuic(right_operation);
Chris@102 168 }
Chris@102 169 else
Chris@102 170 {
Chris@102 171 return op_to_int_xiuc(left_operation)
Chris@102 172 < op_to_int_xiuc(right_operation);
Chris@102 173 }
Chris@102 174 }
Chris@102 175 };
Chris@102 176
Chris@102 177 template <std::size_t OpId>
Chris@102 178 struct less_op_areal_linear
Chris@102 179 : less_op_xxx_linear< OpId, op_to_int<0,1,0,0,2,0> >
Chris@102 180 {};
Chris@102 181
Chris@102 182 template <std::size_t OpId>
Chris@102 183 struct less_op_areal_areal
Chris@102 184 {
Chris@102 185 template <typename Turn>
Chris@102 186 inline bool operator()(Turn const& left, Turn const& right) const
Chris@102 187 {
Chris@102 188 static const std::size_t other_op_id = (OpId + 1) % 2;
Chris@102 189 static op_to_int<0, 1, 2, 3, 4, 0> op_to_int_uixc;
Chris@102 190 static op_to_int<0, 2, 1, 3, 4, 0> op_to_int_iuxc;
Chris@102 191
Chris@102 192 segment_identifier const& left_other_seg_id = left.operations[other_op_id].seg_id;
Chris@102 193 segment_identifier const& right_other_seg_id = right.operations[other_op_id].seg_id;
Chris@102 194
Chris@102 195 typedef typename Turn::turn_operation_type operation_type;
Chris@102 196 operation_type const& left_operation = left.operations[OpId];
Chris@102 197 operation_type const& right_operation = right.operations[OpId];
Chris@102 198
Chris@102 199 if ( left_other_seg_id.multi_index == right_other_seg_id.multi_index )
Chris@102 200 {
Chris@102 201 if ( left_other_seg_id.ring_index == right_other_seg_id.ring_index )
Chris@102 202 {
Chris@102 203 return op_to_int_uixc(left_operation) < op_to_int_uixc(right_operation);
Chris@102 204 }
Chris@102 205 else
Chris@102 206 {
Chris@102 207 if ( left_other_seg_id.ring_index == -1 )
Chris@102 208 {
Chris@102 209 if ( left_operation.operation == overlay::operation_union )
Chris@102 210 return false;
Chris@102 211 else if ( left_operation.operation == overlay::operation_intersection )
Chris@102 212 return true;
Chris@102 213 }
Chris@102 214 else if ( right_other_seg_id.ring_index == -1 )
Chris@102 215 {
Chris@102 216 if ( right_operation.operation == overlay::operation_union )
Chris@102 217 return true;
Chris@102 218 else if ( right_operation.operation == overlay::operation_intersection )
Chris@102 219 return false;
Chris@102 220 }
Chris@102 221
Chris@102 222 return op_to_int_iuxc(left_operation) < op_to_int_iuxc(right_operation);
Chris@102 223 }
Chris@102 224 }
Chris@102 225 else
Chris@102 226 {
Chris@102 227 return op_to_int_uixc(left_operation) < op_to_int_uixc(right_operation);
Chris@102 228 }
Chris@102 229 }
Chris@102 230 };
Chris@102 231
Chris@102 232 template <std::size_t OpId>
Chris@102 233 struct less_other_multi_index
Chris@102 234 {
Chris@102 235 static const std::size_t other_op_id = (OpId + 1) % 2;
Chris@102 236
Chris@102 237 template <typename Turn>
Chris@102 238 inline bool operator()(Turn const& left, Turn const& right) const
Chris@102 239 {
Chris@102 240 return left.operations[other_op_id].seg_id.multi_index
Chris@102 241 < right.operations[other_op_id].seg_id.multi_index;
Chris@102 242 }
Chris@102 243 };
Chris@102 244
Chris@102 245 // sort turns by G1 - source_index == 0 by:
Chris@102 246 // seg_id -> distance -> operation
Chris@102 247 template <std::size_t OpId = 0,
Chris@102 248 typename LessOp = less_op_xxx_linear< OpId, op_to_int<> > >
Chris@102 249 struct less
Chris@102 250 {
Chris@102 251 BOOST_STATIC_ASSERT(OpId < 2);
Chris@102 252
Chris@102 253 template <typename Turn>
Chris@102 254 static inline bool use_fraction(Turn const& left, Turn const& right)
Chris@102 255 {
Chris@102 256 static LessOp less_op;
Chris@102 257
Chris@102 258 return left.operations[OpId].fraction < right.operations[OpId].fraction
Chris@102 259 || ( left.operations[OpId].fraction == right.operations[OpId].fraction
Chris@102 260 && less_op(left, right) );
Chris@102 261 }
Chris@102 262
Chris@102 263 template <typename Turn>
Chris@102 264 inline bool operator()(Turn const& left, Turn const& right) const
Chris@102 265 {
Chris@102 266 segment_identifier const& sl = left.operations[OpId].seg_id;
Chris@102 267 segment_identifier const& sr = right.operations[OpId].seg_id;
Chris@102 268
Chris@102 269 return sl < sr || ( sl == sr && use_fraction(left, right) );
Chris@102 270 }
Chris@102 271 };
Chris@102 272
Chris@102 273 }}} // namespace detail::relate::turns
Chris@102 274 #endif // DOXYGEN_NO_DETAIL
Chris@102 275
Chris@102 276 }} // namespace boost::geometry
Chris@102 277
Chris@102 278 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_TURNS_HPP