summaryrefslogtreecommitdiff
path: root/boost/geometry/strategies/cartesian/cart_intersect.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/strategies/cartesian/cart_intersect.hpp')
-rw-r--r--boost/geometry/strategies/cartesian/cart_intersect.hpp134
1 files changed, 106 insertions, 28 deletions
diff --git a/boost/geometry/strategies/cartesian/cart_intersect.hpp b/boost/geometry/strategies/cartesian/cart_intersect.hpp
index 8a9857376a..0cb5d75457 100644
--- a/boost/geometry/strategies/cartesian/cart_intersect.hpp
+++ b/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.
-// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+// This file was modified by Oracle on 2014, 2016.
+// Modifications copyright (c) 2014-2016, 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
@@ -30,6 +30,7 @@
#include <boost/geometry/algorithms/detail/recalculate.hpp>
#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/promote_integral.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
// Temporary / will be Strategy as template parameter
@@ -37,6 +38,7 @@
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/side_info.hpp>
+#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/strategies/intersection_result.hpp>
#include <boost/geometry/policies/robustness/robust_point_type.hpp>
@@ -64,6 +66,69 @@ struct relate_cartesian_segments
{
typedef typename Policy::return_type return_type;
+ template <typename CoordinateType, typename SegmentRatio>
+ struct segment_intersection_info
+ {
+ typedef typename select_most_precise
+ <
+ CoordinateType, double
+ >::type promoted_type;
+
+ promoted_type comparable_length_a() const
+ {
+ return dx_a * dx_a + dy_a * dy_a;
+ }
+
+ promoted_type comparable_length_b() const
+ {
+ return dx_b * dx_b + dy_b * dy_b;
+ }
+
+ template <typename Point, typename Segment1, typename Segment2>
+ void assign_a(Point& point, Segment1 const& a, Segment2 const& ) const
+ {
+ assign(point, a, dx_a, dy_a, robust_ra);
+ }
+ template <typename Point, typename Segment1, typename Segment2>
+ void assign_b(Point& point, Segment1 const& , Segment2 const& b) const
+ {
+ assign(point, b, dx_b, dy_b, robust_rb);
+ }
+
+ template <typename Point, typename Segment>
+ void assign(Point& point, Segment const& segment, CoordinateType const& dx, CoordinateType const& dy, SegmentRatio const& ratio) const
+ {
+ // Calculate the intersection point based on segment_ratio
+ // Up to now, division was postponed. Here we divide using numerator/
+ // denominator. In case of integer this results in an integer
+ // division.
+ BOOST_GEOMETRY_ASSERT(ratio.denominator() != 0);
+
+ typedef typename promote_integral<CoordinateType>::type promoted_type;
+
+ promoted_type const numerator
+ = boost::numeric_cast<promoted_type>(ratio.numerator());
+ promoted_type const denominator
+ = boost::numeric_cast<promoted_type>(ratio.denominator());
+ promoted_type const dx_promoted = boost::numeric_cast<promoted_type>(dx);
+ promoted_type const dy_promoted = boost::numeric_cast<promoted_type>(dy);
+
+ set<0>(point, get<0, 0>(segment) + boost::numeric_cast
+ <
+ CoordinateType
+ >(numerator * dx_promoted / denominator));
+ set<1>(point, get<0, 1>(segment) + boost::numeric_cast
+ <
+ CoordinateType
+ >(numerator * dy_promoted / denominator));
+ }
+
+ CoordinateType dx_a, dy_a;
+ CoordinateType dx_b, dy_b;
+ SegmentRatio robust_ra;
+ SegmentRatio robust_rb;
+ };
+
template <typename D, typename W, typename ResultType>
static inline void cramers_rule(D const& dx_a, D const& dy_a,
D const& dx_b, D const& dy_b, W const& wx, W const& wy,
@@ -108,16 +173,17 @@ struct relate_cartesian_segments
}
// The main entry-routine, calculating intersections of segments a / b
- template <typename Segment1, typename Segment2, typename RobustPolicy, typename RobustPoint>
+ // NOTE: Robust* types may be the same as Segments' point types
+ template <typename Segment1, typename Segment2,
+ typename RobustPolicy,
+ typename RobustPoint1, typename RobustPoint2>
static inline return_type apply(Segment1 const& a, Segment2 const& b,
- RobustPolicy const& robust_policy,
- RobustPoint const& robust_a1, RobustPoint const& robust_a2,
- RobustPoint const& robust_b1, RobustPoint const& robust_b2)
+ RobustPolicy const& /*robust_policy*/,
+ RobustPoint1 const& robust_a1, RobustPoint1 const& robust_a2,
+ RobustPoint2 const& robust_b1, RobustPoint2 const& robust_b2)
{
- BOOST_CONCEPT_ASSERT( (concept::ConstSegment<Segment1>) );
- BOOST_CONCEPT_ASSERT( (concept::ConstSegment<Segment2>) );
-
- boost::ignore_unused_variable_warning(robust_policy);
+ BOOST_CONCEPT_ASSERT( (concepts::ConstSegment<Segment1>) );
+ BOOST_CONCEPT_ASSERT( (concepts::ConstSegment<Segment2>) );
using geometry::detail::equals::equals_point_point;
bool const a_is_point = equals_point_point(robust_a1, robust_a2);
@@ -159,12 +225,8 @@ struct relate_cartesian_segments
typedef typename select_most_precise
<
- coordinate_type, double
- >::type promoted_type;
-
- typedef typename geometry::coordinate_type
- <
- RobustPoint
+ typename geometry::coordinate_type<RobustPoint1>::type,
+ typename geometry::coordinate_type<RobustPoint2>::type
>::type robust_coordinate_type;
typedef typename segment_ratio_type
@@ -176,7 +238,6 @@ struct relate_cartesian_segments
segment_intersection_info
<
coordinate_type,
- promoted_type,
ratio_type
> sinfo;
@@ -300,12 +361,13 @@ private:
typename RatioType,
typename Segment1,
typename Segment2,
- typename RobustPoint
+ typename RobustPoint1,
+ typename RobustPoint2
>
static inline return_type relate_collinear(Segment1 const& a,
Segment2 const& b,
- RobustPoint const& robust_a1, RobustPoint const& robust_a2,
- RobustPoint const& robust_b1, RobustPoint const& robust_b2,
+ 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)
@@ -335,12 +397,13 @@ private:
typename RatioType,
typename Segment1,
typename Segment2,
- typename RobustType
+ typename RobustType1,
+ typename RobustType2
>
static inline return_type relate_collinear(Segment1 const& a
, Segment2 const& b
- , RobustType oa_1, RobustType oa_2
- , RobustType ob_1, RobustType ob_2
+ , RobustType1 oa_1, RobustType1 oa_2
+ , RobustType2 ob_1, RobustType2 ob_2
)
{
// Calculate the ratios where a starts in b, b starts in a
@@ -373,8 +436,8 @@ private:
// b2 is located w.r.t. a at ratio: (5-2)/5=3/5 (on a)
// a1 is located w.r.t. b at ratio: (2-8)/-3=6/3 (after b ends)
// a2 is located w.r.t. b at ratio: (7-8)/-3=1/3 (on b)
- RobustType const length_a = oa_2 - oa_1; // no abs, see above
- RobustType const length_b = ob_2 - ob_1;
+ RobustType1 const length_a = oa_2 - oa_1; // no abs, see above
+ RobustType2 const length_b = ob_2 - ob_1;
RatioType ra_from(oa_1 - ob_1, length_b);
RatioType ra_to(oa_2 - ob_1, length_b);
@@ -435,12 +498,13 @@ private:
<
typename RatioType,
typename DegenerateSegment,
- typename RobustType
+ typename RobustType1,
+ typename RobustType2
>
static inline return_type relate_one_degenerate(
DegenerateSegment const& degenerate_segment
- , RobustType d
- , RobustType s1, RobustType s2
+ , RobustType1 d
+ , RobustType2 s1, RobustType2 s2
, bool a_degenerate
)
{
@@ -478,6 +542,20 @@ private:
};
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Policy, typename CalculationType>
+struct default_strategy<cartesian_tag, Policy, CalculationType>
+{
+ typedef relate_cartesian_segments<Policy, CalculationType> type;
+};
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
}} // namespace strategy::intersection
}} // namespace boost::geometry