diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/overlay/get_turn_info.hpp')
-rw-r--r-- | boost/geometry/algorithms/detail/overlay/get_turn_info.hpp | 528 |
1 files changed, 261 insertions, 267 deletions
diff --git a/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp b/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp index b8320d9b7b..240b6de036 100644 --- a/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp +++ b/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp @@ -16,9 +16,19 @@ #include <boost/geometry/algorithms/convert.hpp> #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp> +#include <boost/geometry/algorithms/detail/recalculate.hpp> #include <boost/geometry/geometries/segment.hpp> +#include <boost/geometry/policies/robustness/robust_point_type.hpp> +#include <boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp> + +// Silence warning C4127: conditional expression is constant +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable : 4127) +#endif + namespace boost { namespace geometry { @@ -30,7 +40,7 @@ class turn_info_exception : public geometry::exception public: // NOTE: "char" will be replaced by enum in future version - inline turn_info_exception(char const method) + inline turn_info_exception(char const method) { message = "Boost.Geometry Turn exception: "; message += method; @@ -50,7 +60,6 @@ public: namespace detail { namespace overlay { - struct base_turn_handler { // Returns true if both sides are opposite @@ -91,13 +100,32 @@ struct base_turn_handler { both(ti, condition ? operation_union : operation_intersection); } + + template <typename TurnInfo, typename IntersectionInfo> + static inline void assign_point(TurnInfo& ti, + method_type method, + IntersectionInfo const& info, int index) + { + ti.method = method; + BOOST_ASSERT(index >= 0 && unsigned(index) < info.count); // TODO remove this + geometry::convert(info.intersections[index], ti.point); + ti.operations[0].fraction = info.fractions[index].robust_ra; + ti.operations[1].fraction = info.fractions[index].robust_rb; + } + + template <typename IntersectionInfo> + static inline int non_opposite_to_index(IntersectionInfo const& info) + { + return info.fractions[0].robust_rb < info.fractions[1].robust_rb + ? 1 : 0; + } + }; template < - typename TurnInfo, - typename SideStrategy + typename TurnInfo > struct touch_interior : public base_turn_handler { @@ -108,17 +136,18 @@ struct touch_interior : public base_turn_handler typename Point1, typename Point2, typename IntersectionInfo, - typename DirInfo + typename DirInfo, + typename SidePolicy > static inline void apply( - Point1 const& pi, Point1 const& pj, Point1 const& , - Point2 const& qi, Point2 const& qj, Point2 const& qk, + Point1 const& , Point1 const& , Point1 const& , + Point2 const& , Point2 const& , Point2 const& , TurnInfo& ti, IntersectionInfo const& intersection_info, - DirInfo const& dir_info) + DirInfo const& dir_info, + SidePolicy const& side) { - ti.method = method_touch_interior; - geometry::convert(intersection_info.intersections[0], ti.point); + assign_point(ti, method_touch_interior, intersection_info, 0); // Both segments of q touch segment p somewhere in its interior // 1) We know: if q comes from LEFT or RIGHT @@ -130,7 +159,7 @@ struct touch_interior : public base_turn_handler static int const index_q = 1 - Index; int const side_qi_p = dir_info.sides.template get<index_q, 0>(); - int const side_qk_p = SideStrategy::apply(pi, pj, qk); + int const side_qk_p = side.qk_wrt_p1(); if (side_qi_p == -side_qk_p) { @@ -143,7 +172,7 @@ struct touch_interior : public base_turn_handler return; } - int const side_qk_q = SideStrategy::apply(qi, qj, qk); + int const side_qk_q = side.qk_wrt_q1(); if (side_qi_p == -1 && side_qk_p == -1 && side_qk_q == 1) { @@ -203,8 +232,7 @@ struct touch_interior : public base_turn_handler template < - typename TurnInfo, - typename SideStrategy + typename TurnInfo > struct touch : public base_turn_handler { @@ -227,37 +255,34 @@ struct touch : public base_turn_handler typename Point1, typename Point2, typename IntersectionInfo, - typename DirInfo + typename DirInfo, + typename SidePolicy > static inline void apply( - Point1 const& pi, Point1 const& pj, Point1 const& pk, - Point2 const& qi, Point2 const& qj, Point2 const& qk, + Point1 const& , Point1 const& , Point1 const& , + Point2 const& , Point2 const& , Point2 const& , TurnInfo& ti, IntersectionInfo const& intersection_info, - DirInfo const& dir_info) + DirInfo const& dir_info, + SidePolicy const& side) { - ti.method = method_touch; - geometry::convert(intersection_info.intersections[0], ti.point); + assign_point(ti, method_touch, intersection_info, 0); int const side_qi_p1 = dir_info.sides.template get<1, 0>(); - int const side_qk_p1 = SideStrategy::apply(pi, pj, qk); + int const side_qk_p1 = side.qk_wrt_p1(); // If Qi and Qk are both at same side of Pi-Pj, // or collinear (so: not opposite sides) if (! opposite(side_qi_p1, side_qk_p1)) { - int const side_pk_q2 = SideStrategy::apply(qj, qk, pk); - int const side_pk_p = SideStrategy::apply(pi, pj, pk); - int const side_qk_q = SideStrategy::apply(qi, qj, qk); - - bool const both_continue = side_pk_p == 0 && side_qk_q == 0; - bool const robustness_issue_in_continue = both_continue && side_pk_q2 != 0; + int const side_pk_q2 = side.pk_wrt_q2(); + int const side_pk_p = side.pk_wrt_p1(); + int const side_qk_q = side.qk_wrt_q1(); bool const q_turns_left = side_qk_q == 1; bool const block_q = side_qk_p1 == 0 && ! same(side_qi_p1, side_qk_q) - && ! robustness_issue_in_continue ; // If Pk at same side as Qi/Qk @@ -276,7 +301,7 @@ struct touch : public base_turn_handler return; } - int const side_pk_q1 = SideStrategy::apply(qi, qj, pk); + int const side_pk_q1 = side.pk_wrt_q1(); // Collinear opposite case -> block P @@ -329,9 +354,6 @@ struct touch : public base_turn_handler else { // Pk at other side than Qi/Pk - int const side_qk_q = SideStrategy::apply(qi, qj, qk); - bool const q_turns_left = side_qk_q == 1; - ti.operations[0].operation = q_turns_left ? operation_intersection : operation_union; @@ -347,13 +369,13 @@ struct touch : public base_turn_handler else { // From left to right or from right to left - int const side_pk_p = SideStrategy::apply(pi, pj, pk); + int const side_pk_p = side.pk_wrt_p1(); bool const right_to_left = side_qk_p1 == 1; // If p turns into direction of qi (1,2) if (side_pk_p == side_qi_p1) { - int const side_pk_q1 = SideStrategy::apply(qi, qj, pk); + int const side_pk_q1 = side.pk_wrt_q1(); // Collinear opposite case -> block P if (side_pk_q1 == 0) @@ -374,7 +396,7 @@ struct touch : public base_turn_handler // If p turns into direction of qk (4,5) if (side_pk_p == side_qk_p1) { - int const side_pk_q2 = SideStrategy::apply(qj, qk, pk); + int const side_pk_q2 = side.pk_wrt_q2(); // Collinear case -> lines join, continue if (side_pk_q2 == 0) @@ -413,8 +435,7 @@ struct touch : public base_turn_handler template < - typename TurnInfo, - typename SideStrategy + typename TurnInfo > struct equal : public base_turn_handler { @@ -423,22 +444,24 @@ struct equal : public base_turn_handler typename Point1, typename Point2, typename IntersectionInfo, - typename DirInfo + typename DirInfo, + typename SidePolicy > static inline void apply( - Point1 const& pi, Point1 const& pj, Point1 const& pk, - Point2 const& , Point2 const& qj, Point2 const& qk, + Point1 const& , Point1 const& , Point1 const& , + Point2 const& , Point2 const& , Point2 const& , TurnInfo& ti, - IntersectionInfo const& intersection_info, - DirInfo const& ) + IntersectionInfo const& info, + DirInfo const& , + SidePolicy const& side) { - ti.method = method_equal; - // Copy the SECOND intersection point - geometry::convert(intersection_info.intersections[1], ti.point); + // Copy the intersection point in TO direction + assign_point(ti, method_equal, info, non_opposite_to_index(info)); + + int const side_pk_q2 = side.pk_wrt_q2(); + int const side_pk_p = side.pk_wrt_p1(); + int const side_qk_p = side.qk_wrt_p1(); - int const side_pk_q2 = SideStrategy::apply(qj, qk, pk); - int const side_pk_p = SideStrategy::apply(pi, pj, pk); - int const side_qk_p = SideStrategy::apply(pi, pj, qk); // If pk is collinear with qj-qk, they continue collinearly. // This can be on either side of p1 (== q1), or collinear @@ -447,6 +470,7 @@ struct equal : public base_turn_handler if (side_pk_q2 == 0 && side_pk_p == side_qk_p) { both(ti, operation_continue); + return; } @@ -454,8 +478,6 @@ struct equal : public base_turn_handler // If they turn to same side (not opposite sides) if (! opposite(side_pk_p, side_qk_p)) { - int const side_pk_q2 = SideStrategy::apply(qj, qk, pk); - // If pk is left of q2 or collinear: p: union, q: intersection ui_else_iu(side_pk_q2 != -1, ti); } @@ -485,33 +507,32 @@ struct equal_opposite : public base_turn_handler typename DirInfo > static inline void apply(Point1 const& pi, Point2 const& qi, - /* by value: */ TurnInfo tp, + /* by value: */ TurnInfo tp, OutputIterator& out, IntersectionInfo const& intersection_info, DirInfo const& dir_info) { // For equal-opposite segments, normally don't do anything. - if (AssignPolicy::include_opposite) - { - tp.method = method_equal; - for (int i = 0; i < 2; i++) - { - tp.operations[i].operation = operation_opposite; - } - for (unsigned int i = 0; i < intersection_info.count; i++) - { - geometry::convert(intersection_info.intersections[i], tp.point); - AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info); - *out++ = tp; - } - } + if (AssignPolicy::include_opposite) + { + tp.method = method_equal; + for (int i = 0; i < 2; i++) + { + tp.operations[i].operation = operation_opposite; + } + for (unsigned int i = 0; i < intersection_info.count; i++) + { + assign_point(tp, method_none, intersection_info, i); + AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info); + *out++ = tp; + } + } } }; template < - typename TurnInfo, - typename SideStrategy + typename TurnInfo > struct collinear : public base_turn_handler { @@ -543,7 +564,7 @@ struct collinear : public base_turn_handler ROBUSTNESS: p and q are collinear, so you would expect that side qk//p1 == pk//q1. But that is not always the case in near-epsilon ranges. Then decision logic is different. - If p arrives, q is further, so the angle qk//p1 is (normally) + If p arrives, q is further, so the angle qk//p1 is (normally) more precise than pk//p1 */ @@ -552,24 +573,26 @@ struct collinear : public base_turn_handler typename Point1, typename Point2, typename IntersectionInfo, - typename DirInfo + typename DirInfo, + typename SidePolicy > static inline void apply( - Point1 const& pi, Point1 const& pj, Point1 const& pk, - Point2 const& qi, Point2 const& qj, Point2 const& qk, + Point1 const& , Point1 const& , Point1 const& , + Point2 const& , Point2 const& , Point2 const& , TurnInfo& ti, - IntersectionInfo const& intersection_info, - DirInfo const& dir_info) + IntersectionInfo const& info, + DirInfo const& dir_info, + SidePolicy const& side) { - ti.method = method_collinear; - geometry::convert(intersection_info.intersections[1], ti.point); + // Copy the intersection point in TO direction + assign_point(ti, method_collinear, info, non_opposite_to_index(info)); int const arrival = dir_info.arrival[0]; // Should not be 0, this is checked before BOOST_ASSERT(arrival != 0); - int const side_p = SideStrategy::apply(pi, pj, pk); - int const side_q = SideStrategy::apply(qi, qj, qk); + int const side_p = side.pk_wrt_p1(); + int const side_q = side.qk_wrt_q1(); // If p arrives, use p, else use q int const side_p_or_q = arrival == 1 @@ -577,9 +600,6 @@ struct collinear : public base_turn_handler : side_q ; - int const side_pk = SideStrategy::apply(qi, qj, pk); - int const side_qk = SideStrategy::apply(pi, pj, qk); - // See comments above, // resulting in a strange sort of mathematic rule here: // The arrival-info multiplied by the relevant side @@ -587,15 +607,7 @@ struct collinear : public base_turn_handler int const product = arrival * side_p_or_q; - // Robustness: side_p is supposed to be equal to side_pk (because p/q are collinear) - // and side_q to side_qk - bool const robustness_issue = side_pk != side_p || side_qk != side_q; - - if (robustness_issue) - { - handle_robustness(ti, arrival, side_p, side_q, side_pk, side_qk); - } - else if(product == 0) + if(product == 0) { both(ti, operation_continue); } @@ -605,43 +617,11 @@ struct collinear : public base_turn_handler } } - static inline void handle_robustness(TurnInfo& ti, int arrival, - int side_p, int side_q, int side_pk, int side_qk) - { - // We take the longer one, i.e. if q arrives in p (arrival == -1), - // then p exceeds q and we should take p for a union... - - bool use_p_for_union = arrival == -1; - - // ... unless one of the sides consistently directs to the other side - int const consistent_side_p = side_p == side_pk ? side_p : 0; - int const consistent_side_q = side_q == side_qk ? side_q : 0; - if (arrival == -1 && (consistent_side_p == -1 || consistent_side_q == 1)) - { - use_p_for_union = false; - } - if (arrival == 1 && (consistent_side_p == 1 || consistent_side_q == -1)) - { - use_p_for_union = true; - } - - //std::cout << "ROBUSTNESS -> Collinear " - // << " arr: " << arrival - // << " dir: " << side_p << " " << side_q - // << " rev: " << side_pk << " " << side_qk - // << " cst: " << cside_p << " " << cside_q - // << std::boolalpha << " " << use_p_for_union - // << std::endl; - - ui_else_iu(use_p_for_union, ti); - } - }; template < typename TurnInfo, - typename SideStrategy, typename AssignPolicy > struct collinear_opposite : public base_turn_handler @@ -674,14 +654,19 @@ private : template < int Index, - typename Point, + typename Point1, + typename Point2, typename IntersectionInfo > - static inline bool set_tp(Point const& ri, Point const& rj, Point const& rk, + static inline bool set_tp(Point1 const& , Point1 const& , Point1 const& , int side_rk_r, + bool const handle_robustness, + Point2 const& , Point2 const& , int side_rk_s, TurnInfo& tp, IntersectionInfo const& intersection_info) { - int const side_rk_r = SideStrategy::apply(ri, rj, rk); - operation_type blocked = operation_blocked; + boost::ignore_unused_variable_warning(handle_robustness); + boost::ignore_unused_variable_warning(side_rk_s); + + operation_type blocked = operation_blocked; switch(side_rk_r) { @@ -699,16 +684,16 @@ private : // two operations blocked, so the whole point does not need // to be generated. // So return false to indicate nothing is to be done. - if (AssignPolicy::include_opposite) - { - tp.operations[Index].operation = operation_opposite; - blocked = operation_opposite; - } - else - { - return false; - } - break; + if (AssignPolicy::include_opposite) + { + tp.operations[Index].operation = operation_opposite; + blocked = operation_opposite; + } + else + { + return false; + } + break; } // The other direction is always blocked when collinear opposite @@ -717,18 +702,21 @@ private : // If P arrives within Q, set info on P (which is done above, index=0), // this turn-info belongs to the second intersection point, index=1 // (see e.g. figure CLO1) - geometry::convert(intersection_info.intersections[1 - Index], tp.point); + assign_point(tp, method_collinear, intersection_info, 1 - Index); return true; } public: + static inline void empty_transformer(TurnInfo &) {} + template < typename Point1, typename Point2, typename OutputIterator, typename IntersectionInfo, - typename DirInfo + typename DirInfo, + typename SidePolicy > static inline void apply( Point1 const& pi, Point1 const& pj, Point1 const& pk, @@ -739,46 +727,79 @@ public: OutputIterator& out, IntersectionInfo const& intersection_info, - DirInfo const& dir_info) + DirInfo const& dir_info, + SidePolicy const& side) { - TurnInfo tp = tp_model; + apply(pi, pj, pk, qi, qj, qk, tp_model, out, intersection_info, dir_info, side, empty_transformer); + } - tp.method = method_collinear; +public: + template + < + typename Point1, + typename Point2, + typename OutputIterator, + typename IntersectionInfo, + typename DirInfo, + typename SidePolicy, + typename TurnTransformer + > + static inline void apply( + Point1 const& pi, Point1 const& pj, Point1 const& pk, + Point2 const& qi, Point2 const& qj, Point2 const& qk, + + // Opposite collinear can deliver 2 intersection points, + TurnInfo const& tp_model, + OutputIterator& out, + + IntersectionInfo const& intersection_info, + DirInfo const& dir_info, + SidePolicy const& side, + TurnTransformer turn_transformer, + bool const is_pk_valid = true, bool const is_qk_valid = true) + { + TurnInfo tp = tp_model; // If P arrives within Q, there is a turn dependent on P - if (dir_info.arrival[0] == 1 - && set_tp<0>(pi, pj, pk, tp, intersection_info)) + if ( dir_info.arrival[0] == 1 + && is_pk_valid + && set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, intersection_info) ) { + turn_transformer(tp); + AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info); *out++ = tp; } // If Q arrives within P, there is a turn dependent on Q - if (dir_info.arrival[1] == 1 - && set_tp<1>(qi, qj, qk, tp, intersection_info)) + if ( dir_info.arrival[1] == 1 + && is_qk_valid + && set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, intersection_info) ) { + turn_transformer(tp); + AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info); *out++ = tp; } - if (AssignPolicy::include_opposite) - { - // Handle cases not yet handled above - if ((dir_info.arrival[1] == -1 && dir_info.arrival[0] == 0) - || (dir_info.arrival[0] == -1 && dir_info.arrival[1] == 0)) - { - for (int i = 0; i < 2; i++) - { - tp.operations[i].operation = operation_opposite; - } - for (unsigned int i = 0; i < intersection_info.count; i++) - { - geometry::convert(intersection_info.intersections[i], tp.point); - AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info); - *out++ = tp; - } - } - } + if (AssignPolicy::include_opposite) + { + // Handle cases not yet handled above + if ((dir_info.arrival[1] == -1 && dir_info.arrival[0] == 0) + || (dir_info.arrival[0] == -1 && dir_info.arrival[1] == 0)) + { + for (int i = 0; i < 2; i++) + { + tp.operations[i].operation = operation_opposite; + } + for (unsigned int i = 0; i < intersection_info.count; i++) + { + assign_point(tp, method_collinear, intersection_info, i); + AssignPolicy::apply(tp, pi, qi, intersection_info, dir_info); + *out++ = tp; + } + } + } } }; @@ -786,8 +807,7 @@ public: template < - typename TurnInfo, - typename SideStrategy + typename TurnInfo > struct crosses : public base_turn_handler { @@ -805,8 +825,7 @@ struct crosses : public base_turn_handler IntersectionInfo const& intersection_info, DirInfo const& dir_info) { - ti.method = method_crosses; - geometry::convert(intersection_info.intersections[0], ti.point); + assign_point(ti, method_crosses, intersection_info, 0); // In all casees: // If Q crosses P from left to right @@ -820,14 +839,12 @@ struct crosses : public base_turn_handler } }; -template<typename TurnInfo> -struct only_convert +struct only_convert : public base_turn_handler { - template<typename IntersectionInfo> + template<typename TurnInfo, typename IntersectionInfo> static inline void apply(TurnInfo& ti, IntersectionInfo const& intersection_info) { - ti.method = method_collinear; - geometry::convert(intersection_info.intersections[0], ti.point); + assign_point(ti, method_none, intersection_info, 0); // was collinear ti.operations[0].operation = operation_continue; ti.operations[1].operation = operation_continue; } @@ -845,14 +862,14 @@ struct assign_null_policy static bool const include_degenerate = false; static bool const include_opposite = false; - template - < - typename Info, - typename Point1, - typename Point2, - typename IntersectionInfo, - typename DirInfo - > + template + < + typename Info, + typename Point1, + typename Point2, + typename IntersectionInfo, + typename DirInfo + > static inline void apply(Info& , Point1 const& , Point2 const&, IntersectionInfo const&, DirInfo const&) {} @@ -873,48 +890,39 @@ struct assign_null_policy It also defines if a certain class of points (degenerate, non-turns) should be included. */ -template -< - typename Point1, - typename Point2, - typename TurnInfo, - typename AssignPolicy -> +template<typename AssignPolicy> struct get_turn_info { - typedef strategy_intersection - < - typename cs_tag<typename TurnInfo::point_type>::type, - Point1, - Point2, - typename TurnInfo::point_type - > si; - - typedef typename si::segment_intersection_strategy_type strategy; - // Intersect pi-pj with qi-qj - // The points pk and qk are only used do determine more information - // about the turn. - template <typename OutputIterator> + // The points pk and qk are used do determine more information + // about the turn (turn left/right) + template + < + typename Point1, + typename Point2, + typename TurnInfo, + typename RobustPolicy, + typename OutputIterator + > static inline OutputIterator apply( Point1 const& pi, Point1 const& pj, Point1 const& pk, Point2 const& qi, Point2 const& qj, Point2 const& qk, + bool /*is_p_first*/, bool /*is_p_last*/, + bool /*is_q_first*/, bool /*is_q_last*/, TurnInfo const& tp_model, + RobustPolicy const& robust_policy, OutputIterator out) { - typedef model::referring_segment<Point1 const> segment_type1; - typedef model::referring_segment<Point1 const> segment_type2; - segment_type1 p1(pi, pj), p2(pj, pk); - segment_type2 q1(qi, qj), q2(qj, qk); + typedef intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy> + inters_info; - typename strategy::return_type result = strategy::apply(p1, q1); + inters_info inters(pi, pj, pk, qi, qj, qk, robust_policy); - char const method = result.template get<1>().how; + char const method = inters.d_info().how; // Copy, to copy possibly extended fields TurnInfo tp = tp_model; - // Select method and apply switch(method) { @@ -922,11 +930,10 @@ struct get_turn_info case 'f' : // collinear, "from" case 's' : // starts from the middle if (AssignPolicy::include_no_turn - && result.template get<0>().count > 0) + && inters.i_info().count > 0) { - only_convert<TurnInfo>::apply(tp, - result.template get<0>()); - AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>()); + only_convert::apply(tp, inters.i_info()); + AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info()); *out++ = tp; } break; @@ -938,113 +945,94 @@ struct get_turn_info { typedef touch_interior < - TurnInfo, - typename si::side_strategy_type + TurnInfo > policy; // If Q (1) arrives (1) - if (result.template get<1>().arrival[1] == 1) + if ( inters.d_info().arrival[1] == 1 ) { policy::template apply<0>(pi, pj, pk, qi, qj, qk, - tp, result.template get<0>(), result.template get<1>()); + tp, inters.i_info(), inters.d_info(), + inters.sides()); } else { // Swap p/q + side_calculator + < + typename inters_info::robust_point2_type, + typename inters_info::robust_point1_type + > swapped_side_calc(inters.rqi(), inters.rqj(), inters.rqk(), + inters.rpi(), inters.rpj(), inters.rpk()); policy::template apply<1>(qi, qj, qk, pi, pj, pk, - tp, result.template get<0>(), result.template get<1>()); + tp, inters.i_info(), inters.d_info(), + swapped_side_calc); } - AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>()); + AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info()); *out++ = tp; } break; case 'i' : { - typedef crosses - < - TurnInfo, - typename si::side_strategy_type - > policy; - - policy::apply(pi, pj, pk, qi, qj, qk, - tp, result.template get<0>(), result.template get<1>()); - AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>()); + crosses<TurnInfo>::apply(pi, pj, pk, qi, qj, qk, + tp, inters.i_info(), inters.d_info()); + AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info()); *out++ = tp; } break; case 't' : { // Both touch (both arrive there) - typedef touch - < - TurnInfo, - typename si::side_strategy_type - > policy; - - policy::apply(pi, pj, pk, qi, qj, qk, - tp, result.template get<0>(), result.template get<1>()); - AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>()); + touch<TurnInfo>::apply(pi, pj, pk, qi, qj, qk, + tp, inters.i_info(), inters.d_info(), inters.sides()); + AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info()); *out++ = tp; } break; case 'e': { - if (! result.template get<1>().opposite) + if ( ! inters.d_info().opposite ) { // Both equal // or collinear-and-ending at intersection point - typedef equal - < - TurnInfo, - typename si::side_strategy_type - > policy; - - policy::apply(pi, pj, pk, qi, qj, qk, - tp, result.template get<0>(), result.template get<1>()); - AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>()); + equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk, + tp, inters.i_info(), inters.d_info(), inters.sides()); + AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info()); *out++ = tp; } - else - { + else + { equal_opposite < TurnInfo, AssignPolicy >::apply(pi, qi, - tp, out, result.template get<0>(), result.template get<1>()); - } + tp, out, inters.i_info(), inters.d_info()); + } } break; case 'c' : { // Collinear - if (! result.template get<1>().opposite) + if ( ! inters.d_info().opposite ) { - if (result.template get<1>().arrival[0] == 0) + if ( inters.d_info().arrival[0] == 0 ) { // Collinear, but similar thus handled as equal - equal - < - TurnInfo, - typename si::side_strategy_type - >::apply(pi, pj, pk, qi, qj, qk, - tp, result.template get<0>(), result.template get<1>()); + equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk, + tp, inters.i_info(), inters.d_info(), inters.sides()); // override assigned method tp.method = method_collinear; } else { - collinear - < - TurnInfo, - typename si::side_strategy_type - >::apply(pi, pj, pk, qi, qj, qk, - tp, result.template get<0>(), result.template get<1>()); + collinear<TurnInfo>::apply(pi, pj, pk, qi, qj, qk, + tp, inters.i_info(), inters.d_info(), inters.sides()); } - AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>()); + AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info()); *out++ = tp; } else @@ -1052,10 +1040,9 @@ struct get_turn_info collinear_opposite < TurnInfo, - typename si::side_strategy_type, AssignPolicy >::apply(pi, pj, pk, qi, qj, qk, - tp, out, result.template get<0>(), result.template get<1>()); + tp, out, inters.i_info(), inters.d_info(), inters.sides()); } } break; @@ -1064,14 +1051,17 @@ struct get_turn_info // degenerate points if (AssignPolicy::include_degenerate) { - only_convert<TurnInfo>::apply(tp, result.template get<0>()); - AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>()); + only_convert::apply(tp, inters.i_info()); + AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info()); *out++ = tp; } } break; default : { +#if defined(BOOST_GEOMETRY_DEBUG_ROBUSTNESS) + std::cout << "TURN: Unknown method: " << method << std::endl; +#endif #if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW) throw turn_info_exception(method); #endif @@ -1091,4 +1081,8 @@ struct get_turn_info }} // namespace boost::geometry +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HPP |