[get_turns][strategies] Optimize get_turns().

The optimization is based on the fact that in the most cases the segments
handled in the TurnInfoPolicy are disjoint. For disjoint segments first
the points are rescaled, then the test for disjoint is run, next the
TurnInfoPolicy just returns and the next pair of segments is handled.
Therefore to optimze the get_turns() this commit changes two things:
1. the cart_intersect strategy may return just after the calculation of sides
   for the first segment (2 sides calculation instead of 4),
2. the points are rescaled only one time in the intersection_helper,
   already rescaled points are passed into the intersection strategy
This commit is contained in:
Adam Wulkiewicz
2015-07-03 21:08:56 +02:00
parent 2fe55e07dd
commit eec0091bc0
2 changed files with 20 additions and 11 deletions

View File

@@ -217,7 +217,9 @@ public:
: base_t(pi, pj, pk, qi, qj, qk, robust_policy)
, m_result(strategy::apply(segment_type1(pi, pj),
segment_type2(qi, qj),
robust_policy))
robust_policy,
base_t::rpi(), base_t::rpj(),
base_t::rqi(), base_t::rqj()))
, m_robust_policy(robust_policy)
{}

View File

@@ -119,15 +119,10 @@ struct relate_cartesian_segments
boost::ignore_unused_variable_warning(robust_policy);
typedef typename select_calculation_type
<Segment1, Segment2, CalculationType>::type coordinate_type;
using geometry::detail::equals::equals_point_point;
bool const a_is_point = equals_point_point(robust_a1, robust_a2);
bool const b_is_point = equals_point_point(robust_b1, robust_b2);
typedef side::side_by_triangle<coordinate_type> side;
if(a_is_point && b_is_point)
{
return equals_point_point(robust_a1, robust_b2)
@@ -136,20 +131,32 @@ struct relate_cartesian_segments
;
}
typedef typename select_calculation_type
<Segment1, Segment2, CalculationType>::type coordinate_type;
typedef side::side_by_triangle<coordinate_type> 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<1>(side::apply(robust_a1, robust_a2, robust_b1),
side::apply(robust_a1, robust_a2, robust_b2));
bool collinear = sides.collinear();
if (sides.same<0>() || sides.same<1>())
if (sides.same<0>())
{
// Both points are at same side of other segment, we can leave
return Policy::disjoint();
}
sides.set<1>(side::apply(robust_a1, robust_a2, robust_b1),
side::apply(robust_a1, robust_a2, robust_b2));
if (sides.same<1>())
{
// Both points are at same side of other segment, we can leave
return Policy::disjoint();
}
bool collinear = sides.collinear();
typedef typename select_most_precise
<
coordinate_type, double