diff --git a/include/boost/geometry/strategies/cartesian/cart_intersect.hpp b/include/boost/geometry/strategies/cartesian/cart_intersect.hpp index 0cb5d7545..1f6f56d66 100644 --- a/include/boost/geometry/strategies/cartesian/cart_intersect.hpp +++ b/include/boost/geometry/strategies/cartesian/cart_intersect.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2016. -// Modifications copyright (c) 2014-2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2016, 2017. +// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -33,13 +33,14 @@ #include #include -// Temporary / will be Strategy as template parameter -#include +#include #include - -#include +#include #include #include +#include +#include +#include #include #include @@ -61,10 +62,38 @@ namespace strategy { namespace intersection /*! \see http://mathworld.wolfram.com/Line-LineIntersection.html */ -template +template struct relate_cartesian_segments { - typedef typename Policy::return_type return_type; + typedef side::side_by_triangle side_strategy_type; + + static inline side_strategy_type get_side_strategy() + { + return side_strategy_type(); + } + + template + struct point_in_geometry_strategy + { + typedef strategy::within::winding + < + typename point_type::type, + typename point_type::type, + side_strategy_type, + CalculationType + > type; + }; + + template + static inline typename point_in_geometry_strategy::type + get_point_in_geometry_strategy() + { + typedef typename point_in_geometry_strategy + < + Geometry1, Geometry2 + >::type strategy_type; + return strategy_type(); + } template struct segment_intersection_info @@ -144,9 +173,16 @@ struct relate_cartesian_segments // Relate segments a and b - template - static inline return_type apply(Segment1 const& a, Segment2 const& b, - RobustPolicy const& robust_policy) + template + < + typename Segment1, + typename Segment2, + typename Policy, + typename RobustPolicy + > + static inline typename Policy::return_type + apply(Segment1 const& a, Segment2 const& b, + Policy const& policy, RobustPolicy const& robust_policy) { // type them all as in Segment1 - TODO reconsider this, most precise? typedef typename geometry::point_type::type point_type; @@ -169,18 +205,25 @@ struct relate_cartesian_segments geometry::recalculate(b0_rob, b0, robust_policy); geometry::recalculate(b1_rob, b1, robust_policy); - return apply(a, b, robust_policy, a0_rob, a1_rob, b0_rob, b1_rob); + return apply(a, b, policy, robust_policy, a0_rob, a1_rob, b0_rob, b1_rob); } // The main entry-routine, calculating intersections of segments a / b // NOTE: Robust* types may be the same as Segments' point types - template - static inline return_type apply(Segment1 const& a, Segment2 const& b, - RobustPolicy const& /*robust_policy*/, - RobustPoint1 const& robust_a1, RobustPoint1 const& robust_a2, - RobustPoint2 const& robust_b1, RobustPoint2 const& robust_b2) + template + < + typename Segment1, + typename Segment2, + typename Policy, + typename RobustPolicy, + typename RobustPoint1, + typename RobustPoint2 + > + static inline typename Policy::return_type + apply(Segment1 const& a, Segment2 const& b, + Policy const&, RobustPolicy const& /*robust_policy*/, + RobustPoint1 const& robust_a1, RobustPoint1 const& robust_a2, + RobustPoint2 const& robust_b1, RobustPoint2 const& robust_b2) { BOOST_CONCEPT_ASSERT( (concepts::ConstSegment) ); BOOST_CONCEPT_ASSERT( (concepts::ConstSegment) ); @@ -197,14 +240,9 @@ struct relate_cartesian_segments ; } - typedef typename select_calculation_type - ::type coordinate_type; - - typedef side::side_by_triangle side; - side_info sides; - sides.set<0>(side::apply(robust_b1, robust_b2, robust_a1), - side::apply(robust_b1, robust_b2, robust_a2)); + sides.set<0>(side_strategy_type::apply(robust_b1, robust_b2, robust_a1), + side_strategy_type::apply(robust_b1, robust_b2, robust_a2)); if (sides.same<0>()) { @@ -212,8 +250,8 @@ struct relate_cartesian_segments return Policy::disjoint(); } - sides.set<1>(side::apply(robust_a1, robust_a2, robust_b1), - side::apply(robust_a1, robust_a2, robust_b2)); + sides.set<1>(side_strategy_type::apply(robust_a1, robust_a2, robust_b1), + side_strategy_type::apply(robust_a1, robust_a2, robust_b2)); if (sides.same<1>()) { @@ -230,16 +268,16 @@ struct relate_cartesian_segments >::type robust_coordinate_type; typedef typename segment_ratio_type - < - typename geometry::point_type::type, // TODO: most precise point? - RobustPolicy - >::type ratio_type; + < + typename geometry::point_type::type, // TODO: most precise point? + RobustPolicy + >::type ratio_type; segment_intersection_info - < - coordinate_type, - ratio_type - > sinfo; + < + typename select_calculation_type::type, + ratio_type + > sinfo; sinfo.dx_a = get<1, 0>(a) - get<0, 0>(a); // distance in x-dir sinfo.dx_b = get<1, 0>(b) - get<0, 0>(b); @@ -303,14 +341,14 @@ struct relate_cartesian_segments if (collinear_use_first.first) { - return relate_collinear<0, ratio_type>(a, b, + return relate_collinear<0, Policy, ratio_type>(a, b, robust_a1, robust_a2, robust_b1, robust_b2, a_is_point, b_is_point); } else { // Y direction contains larger segments (maybe dx is zero) - return relate_collinear<1, ratio_type>(a, b, + return relate_collinear<1, Policy, ratio_type>(a, b, robust_a1, robust_a2, robust_b1, robust_b2, a_is_point, b_is_point); } @@ -358,33 +396,35 @@ private: template < std::size_t Dimension, + typename Policy, typename RatioType, typename Segment1, typename Segment2, typename RobustPoint1, typename RobustPoint2 > - static inline return_type relate_collinear(Segment1 const& a, - Segment2 const& b, - RobustPoint1 const& robust_a1, RobustPoint1 const& robust_a2, - RobustPoint2 const& robust_b1, RobustPoint2 const& robust_b2, - bool a_is_point, bool b_is_point) + static inline typename Policy::return_type + relate_collinear(Segment1 const& a, + Segment2 const& b, + RobustPoint1 const& robust_a1, RobustPoint1 const& robust_a2, + RobustPoint2 const& robust_b1, RobustPoint2 const& robust_b2, + bool a_is_point, bool b_is_point) { if (a_is_point) { - return relate_one_degenerate(a, + return relate_one_degenerate(a, get(robust_a1), get(robust_b1), get(robust_b2), true); } if (b_is_point) { - return relate_one_degenerate(b, + return relate_one_degenerate(b, get(robust_b1), get(robust_a1), get(robust_a2), false); } - return relate_collinear(a, b, + return relate_collinear(a, b, get(robust_a1), get(robust_a2), get(robust_b1), @@ -394,17 +434,17 @@ private: /// Relate segments known collinear template < + typename Policy, typename RatioType, typename Segment1, typename Segment2, typename RobustType1, typename RobustType2 > - static inline return_type relate_collinear(Segment1 const& a - , Segment2 const& b - , RobustType1 oa_1, RobustType1 oa_2 - , RobustType2 ob_1, RobustType2 ob_2 - ) + static inline typename Policy::return_type + relate_collinear(Segment1 const& a, Segment2 const& b, + RobustType1 oa_1, RobustType1 oa_2, + RobustType2 ob_1, RobustType2 ob_2) { // Calculate the ratios where a starts in b, b starts in a // a1--------->a2 (2..7) @@ -496,17 +536,16 @@ private: /// Relate segments where one is degenerate template < + typename Policy, typename RatioType, typename DegenerateSegment, typename RobustType1, typename RobustType2 > - static inline return_type relate_one_degenerate( - DegenerateSegment const& degenerate_segment - , RobustType1 d - , RobustType2 s1, RobustType2 s2 - , bool a_degenerate - ) + static inline typename Policy::return_type + relate_one_degenerate(DegenerateSegment const& degenerate_segment, + RobustType1 d, RobustType2 s1, RobustType2 s2, + bool a_degenerate) { // Calculate the ratios where ds starts in s // a1--------->a2 (2..6) @@ -546,10 +585,10 @@ private: namespace services { -template -struct default_strategy +template +struct default_strategy { - typedef relate_cartesian_segments type; + typedef relate_cartesian_segments type; }; } // namespace services @@ -558,6 +597,69 @@ struct default_strategy }} // namespace strategy::intersection +namespace strategy +{ + +namespace within { namespace services +{ + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +}} // within::services + +namespace covered_by { namespace services +{ + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_cartesian_segments<> type; +}; + +}} // within::services + +} // strategy + }} // namespace boost::geometry diff --git a/include/boost/geometry/strategies/intersection.hpp b/include/boost/geometry/strategies/intersection.hpp index f51c5cb20..e5662c9e4 100644 --- a/include/boost/geometry/strategies/intersection.hpp +++ b/include/boost/geometry/strategies/intersection.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2016, Oracle and/or its affiliates. +// Copyright (c) 2016-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -30,10 +30,9 @@ namespace services \brief Traits class binding a segments intersection strategy to a coordinate system \ingroup util \tparam CSTag tag of coordinate system of point-type -\tparam Policy intersection policy \tparam CalculationType \tparam_calculation */ -template +template struct default_strategy { BOOST_MPL_ASSERT_MSG diff --git a/include/boost/geometry/strategies/intersection_strategies.hpp b/include/boost/geometry/strategies/intersection_strategies.hpp index 0452c4692..3b836ea51 100644 --- a/include/boost/geometry/strategies/intersection_strategies.hpp +++ b/include/boost/geometry/strategies/intersection_strategies.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2016. -// Modifications copyright (c) 2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2016, 2017. +// Modifications copyright (c) 2016-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -70,17 +70,18 @@ private : > ip_type; public: + typedef policies::relate::segments_tupled + < + policies::relate::segments_intersection_points + < + ip_type + > , + policies::relate::segments_direction + > intersection_policy_type; + typedef typename strategy::intersection::services::default_strategy < Tag, - policies::relate::segments_tupled - < - policies::relate::segments_intersection_points - < - ip_type - > , - policies::relate::segments_direction - >, CalculationType >::type segment_intersection_strategy_type; diff --git a/include/boost/geometry/strategies/spherical/intersection.hpp b/include/boost/geometry/strategies/spherical/intersection.hpp index 4ffc853aa..b8b8bf93e 100644 --- a/include/boost/geometry/strategies/spherical/intersection.hpp +++ b/include/boost/geometry/strategies/spherical/intersection.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2016, Oracle and/or its affiliates. +// Copyright (c) 2016-2017, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -32,9 +32,14 @@ #include -#include +#include +#include #include #include +#include +#include +#include +#include #include #include @@ -68,10 +73,38 @@ namespace strategy { namespace intersection // For now, intersection points near the endpoints are checked explicitly if needed (if the IP is near the endpoint) // to generate precise result for them. Only the crossing (i) case may suffer from lower precision. -template +template struct relate_spherical_segments { - typedef typename Policy::return_type return_type; + typedef side::spherical_side_formula side_strategy_type; + + static inline side_strategy_type get_side_strategy() + { + return side_strategy_type(); + } + + template + struct point_in_geometry_strategy + { + typedef strategy::within::winding + < + typename point_type::type, + typename point_type::type, + side_strategy_type, + CalculationType + > type; + }; + + template + static inline typename point_in_geometry_strategy::type + get_point_in_geometry_strategy() + { + typedef typename point_in_geometry_strategy + < + Geometry1, Geometry2 + >::type strategy_type; + return strategy_type(); + } enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 }; @@ -137,9 +170,16 @@ struct relate_spherical_segments }; // Relate segments a and b - template - static inline return_type apply(Segment1 const& a, Segment2 const& b, - RobustPolicy const& robust_policy) + template + < + typename Segment1, + typename Segment2, + typename Policy, + typename RobustPolicy + > + static inline typename Policy::return_type + apply(Segment1 const& a, Segment2 const& b, + Policy const& policy, RobustPolicy const& robust_policy) { typedef typename point_type::type point1_t; typedef typename point_type::type point2_t; @@ -152,14 +192,23 @@ struct relate_spherical_segments detail::assign_point_from_index<0>(b, b1); detail::assign_point_from_index<1>(b, b2); - return apply(a, b, robust_policy, a1, a2, b1, b2); + return apply(a, b, policy, robust_policy, a1, a2, b1, b2); } // Relate segments a and b - template - static inline return_type apply(Segment1 const& a, Segment2 const& b, - RobustPolicy const&, - Point1 const& a1, Point1 const& a2, Point2 const& b1, Point2 const& b2) + template + < + typename Segment1, + typename Segment2, + typename Policy, + typename RobustPolicy, + typename Point1, + typename Point2 + > + static inline typename Policy::return_type + apply(Segment1 const& a, Segment2 const& b, + Policy const&, RobustPolicy const&, + Point1 const& a1, Point1 const& a2, Point2 const& b1, Point2 const& b2) { BOOST_CONCEPT_ASSERT( (concepts::ConstSegment) ); BOOST_CONCEPT_ASSERT( (concepts::ConstSegment) ); @@ -275,12 +324,12 @@ struct relate_spherical_segments { if (a_is_point) { - return collinear_one_degenerted(a, true, b1, b2, a1, a2, b1v, b2v, norm2, a1v); + return collinear_one_degenerted(a, true, b1, b2, a1, a2, b1v, b2v, norm2, a1v); } else if (b_is_point) { // b2 used to be consistent with (degenerated) checks above (is it needed?) - return collinear_one_degenerted(b, false, a1, a2, b1, b2, a1v, a2v, norm1, b1v); + return collinear_one_degenerted(b, false, a1, a2, b1, b2, a1v, a2v, norm1, b1v); } else { @@ -385,12 +434,13 @@ struct relate_spherical_segments } private: - template - static inline return_type collinear_one_degenerted(Segment const& segment, bool degenerated_a, - Point1 const& a1, Point1 const& a2, - Point2 const& b1, Point2 const& b2, - Vec3d const& v1, Vec3d const& v2, Vec3d const& norm, - Vec3d const& vother) + template + static inline typename Policy::return_type + collinear_one_degenerted(Segment const& segment, bool degenerated_a, + Point1 const& a1, Point1 const& a2, + Point2 const& b1, Point2 const& b2, + Vec3d const& v1, Vec3d const& v2, Vec3d const& norm, + Vec3d const& vother) { CalcT dist_1_2, dist_1_o; return ! calculate_collinear_data(a1, a2, b1, b2, v1, v2, norm, vother, dist_1_2, dist_1_o) @@ -671,22 +721,22 @@ private: namespace services { -/*template -struct default_strategy +/*template +struct default_strategy { - typedef relate_spherical_segments type; + typedef relate_spherical_segments type; };*/ -template -struct default_strategy +template +struct default_strategy { - typedef relate_spherical_segments type; + typedef relate_spherical_segments type; }; -template -struct default_strategy +template +struct default_strategy { - typedef relate_spherical_segments type; + typedef relate_spherical_segments type; }; } // namespace services @@ -695,6 +745,71 @@ struct default_strategy }} // namespace strategy::intersection + +namespace strategy +{ + +namespace within { namespace services +{ + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +}} // within::services + +namespace covered_by { namespace services +{ + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +template +struct default_strategy +{ + typedef strategy::intersection::relate_spherical_segments<> type; +}; + +}} // within::services + +} // strategy + + }} // namespace boost::geometry