summaryrefslogtreecommitdiff
path: root/boost/geometry/policies/relate/intersection_points.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/policies/relate/intersection_points.hpp')
-rw-r--r--boost/geometry/policies/relate/intersection_points.hpp32
1 files changed, 29 insertions, 3 deletions
diff --git a/boost/geometry/policies/relate/intersection_points.hpp b/boost/geometry/policies/relate/intersection_points.hpp
index 082dc4ca7f..50f9b43122 100644
--- a/boost/geometry/policies/relate/intersection_points.hpp
+++ b/boost/geometry/policies/relate/intersection_points.hpp
@@ -18,6 +18,7 @@
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/strategies/side_info.hpp>
#include <boost/geometry/util/promote_integral.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
@@ -60,7 +61,7 @@ struct segments_intersection_points
// Up to now, division was postponed. Here we divide using numerator/
// denominator. In case of integer this results in an integer
// division.
- BOOST_ASSERT(ratio.denominator() != 0);
+ BOOST_GEOMETRY_ASSERT(ratio.denominator() != 0);
typedef typename promote_integral<coordinate_type>::type promoted_type;
@@ -81,7 +82,6 @@ struct segments_intersection_points
>(numerator * dy_promoted / denominator));
}
-
template
<
typename Segment1,
@@ -95,7 +95,33 @@ struct segments_intersection_points
return_type result;
result.count = 1;
- if (sinfo.robust_ra < sinfo.robust_rb)
+ bool use_a = true;
+
+ // Prefer one segment if one is on or near an endpoint
+ bool const a_near_end = sinfo.robust_ra.near_end();
+ bool const b_near_end = sinfo.robust_rb.near_end();
+ if (a_near_end && ! b_near_end)
+ {
+ use_a = true;
+ }
+ else if (b_near_end && ! a_near_end)
+ {
+ use_a = false;
+ }
+ else
+ {
+ // Prefer shorter segment
+ typedef typename SegmentIntersectionInfo::promoted_type ptype;
+ ptype const len_a = sinfo.dx_a * sinfo.dx_a + sinfo.dy_a * sinfo.dy_a;
+ ptype const len_b = sinfo.dx_b * sinfo.dx_b + sinfo.dy_b * sinfo.dy_b;
+ if (len_b < len_a)
+ {
+ use_a = false;
+ }
+ // else use_a is true but was already assigned like that
+ }
+
+ if (use_a)
{
assign(result.intersections[0], s1, sinfo.robust_ra,
sinfo.dx_a, sinfo.dy_a);