File indexing completed on 2025-01-18 09:35:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_TURNS_COMPARE_TURNS_HPP
0012 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_TURNS_COMPARE_TURNS_HPP
0013
0014 #include <cstddef>
0015 #include <functional>
0016
0017 #include <boost/geometry/util/math.hpp>
0018 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
0019
0020
0021 namespace boost { namespace geometry
0022 {
0023
0024 namespace detail { namespace turns
0025 {
0026
0027
0028
0029
0030
0031 template
0032 <
0033 typename IdLess = std::less<signed_size_type>,
0034 int N = 0, int U = 1, int I = 2, int B = 3, int C = 4, int O = 0,
0035 std::size_t OpId = 0
0036 >
0037 struct less_seg_fraction_other_op
0038 {
0039 BOOST_STATIC_ASSERT(OpId < 2);
0040 static const std::size_t other_op_id = (OpId + 1) % 2;
0041
0042 template <typename Op>
0043 static inline int order_op(Op const& op)
0044 {
0045 switch (op.operation)
0046 {
0047 case detail::overlay::operation_none : return N;
0048 case detail::overlay::operation_union : return U;
0049 case detail::overlay::operation_intersection : return I;
0050 case detail::overlay::operation_blocked : return B;
0051 case detail::overlay::operation_continue : return C;
0052 case detail::overlay::operation_opposite : return O;
0053 }
0054 return -1;
0055 }
0056
0057 template <typename Op>
0058 static inline bool use_operation(Op const& left, Op const& right)
0059 {
0060 return order_op(left) < order_op(right);
0061 }
0062
0063 template <typename Turn>
0064 static inline bool use_other_id(Turn const& left, Turn const& right)
0065 {
0066 segment_identifier const& left_other_seg_id = left.operations[other_op_id].seg_id;
0067 segment_identifier const& right_other_seg_id = right.operations[other_op_id].seg_id;
0068
0069 if ( left_other_seg_id.multi_index != right_other_seg_id.multi_index )
0070 {
0071 return left_other_seg_id.multi_index < right_other_seg_id.multi_index;
0072 }
0073 if ( left_other_seg_id.ring_index != right_other_seg_id.ring_index )
0074 {
0075 return left_other_seg_id.ring_index != right_other_seg_id.ring_index;
0076 }
0077 if ( left_other_seg_id.segment_index != right_other_seg_id.segment_index )
0078 {
0079 return IdLess()(left_other_seg_id.segment_index,
0080 right_other_seg_id.segment_index);
0081 }
0082 return use_operation(left.operations[OpId], right.operations[OpId]);
0083 }
0084
0085 template <typename Turn>
0086 static inline bool use_fraction(Turn const& left, Turn const& right)
0087 {
0088 return
0089 geometry::math::equals(left.operations[OpId].fraction,
0090 right.operations[OpId].fraction)
0091 ?
0092 use_other_id(left, right)
0093 :
0094 (left.operations[OpId].fraction < right.operations[OpId].fraction)
0095 ;
0096 }
0097
0098 template <typename Turn>
0099 inline bool operator()(Turn const& left, Turn const& right) const
0100 {
0101 segment_identifier const& sl = left.operations[OpId].seg_id;
0102 segment_identifier const& sr = right.operations[OpId].seg_id;
0103
0104 return sl < sr || ( sl == sr && use_fraction(left, right) );
0105 }
0106 };
0107
0108
0109
0110
0111
0112 }}
0113
0114 }}
0115
0116
0117 #endif