Skip to content

Commit

Permalink
[strategies] prevent integer overflow during segment touch ratio calc…
Browse files Browse the repository at this point in the history
…ulation
  • Loading branch information
Anton Kovalev authored and Anton Kovalev committed Jun 2, 2017
1 parent 5364bbb commit 2524f4e
Showing 1 changed file with 48 additions and 15 deletions.
63 changes: 48 additions & 15 deletions include/boost/geometry/strategies/cartesian/intersection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,24 +340,57 @@ struct cartesian_segments
// (only calculated for non-collinear segments)
if (! collinear)
{
math::detail::equals_factor_policy<robust_coordinate_type>
policy(robust_dx_a, robust_dy_a, robust_dx_b, robust_dy_b);

robust_coordinate_type const zero = 0;

robust_coordinate_type robust_da0, robust_da;
robust_coordinate_type robust_db0, robust_db;

cramers_rule(robust_dx_a, robust_dy_a, robust_dx_b, robust_dy_b,
get<0>(robust_a1) - get<0>(robust_b1),
get<1>(robust_a1) - get<1>(robust_b1),
robust_da0, robust_da);
bool robust_da0_is_zero = false;
if (sides.get<0, 0>() == 0)
{
robust_da0 = 1;
robust_da = 0;
}
else if (sides.get<0, 1>() == 0)
{
robust_da0 = 1;
robust_da = 1;
}
else
{
cramers_rule(robust_dx_a, robust_dy_a, robust_dx_b, robust_dy_b,
get<0>(robust_a1) - get<0>(robust_b1),
get<1>(robust_a1) - get<1>(robust_b1),
robust_da0, robust_da);

cramers_rule(robust_dx_b, robust_dy_b, robust_dx_a, robust_dy_a,
get<0>(robust_b1) - get<0>(robust_a1),
get<1>(robust_b1) - get<1>(robust_a1),
robust_db0, robust_db);
robust_da0_is_zero = math::detail::equals_by_policy(robust_da0, zero, policy);
}

math::detail::equals_factor_policy<robust_coordinate_type>
policy(robust_dx_a, robust_dy_a, robust_dx_b, robust_dy_b);
robust_coordinate_type const zero = 0;
if (math::detail::equals_by_policy(robust_da0, zero, policy)
|| math::detail::equals_by_policy(robust_db0, zero, policy))
bool robust_db0_is_zero = false;
if (sides.get<1, 0>() == 0)
{
robust_db0 = 1;
robust_db = 0;
}
else if (sides.get<1, 1>() == 0)
{
robust_db0 = 1;
robust_db = 1;
}
else
{
cramers_rule(robust_dx_b, robust_dy_b, robust_dx_a, robust_dy_a,
get<0>(robust_b1) - get<0>(robust_a1),
get<1>(robust_b1) - get<1>(robust_a1),
robust_db0, robust_db);

robust_db0_is_zero = math::detail::equals_by_policy(robust_db0, zero, policy);
}

if (robust_da0_is_zero || robust_db0_is_zero)
{
// If this is the case, no rescaling is done for FP precision.
// We set it to collinear, but it indicates a robustness issue.
Expand Down Expand Up @@ -537,7 +570,7 @@ struct cartesian_segments
int const a2_wrt_b = position_value(oa_2, ob_1, ob_2);
int const b1_wrt_a = position_value(ob_1, oa_1, oa_2);
int const b2_wrt_a = position_value(ob_2, oa_1, oa_2);

// fix the ratios if necessary
// CONSIDER: fixing ratios also in other cases, if they're inconsistent
// e.g. if ratio == 1 or 0 (so IP at the endpoint)
Expand All @@ -554,7 +587,7 @@ struct cartesian_segments
{
ra_from.assign(1, 1);
rb_to.assign(0, 1);
}
}

if (a2_wrt_b == 1)
{
Expand Down

0 comments on commit 2524f4e

Please sign in to comment.