[get_turns] fix invalid equal<> use (convert() for uninitialized Point) in get_turn_info_for_endpoints and get_turn_info_linear_areal

This commit is contained in:
Adam Wulkiewicz
2014-03-29 14:08:11 +01:00
parent 830a073c0d
commit b0221bcda1
2 changed files with 83 additions and 17 deletions

View File

@@ -412,14 +412,13 @@ struct get_turn_info_for_endpoint
geometry::convert(i2, i2_conv);
side_calculator<Point1, Point2> side_calc(i2_conv, i1, j1, i2, j2, k2);
TurnInfo tp = tp_model;
equal<TurnInfo>::apply(i2_conv, i1, j1, i2, j2, k2,
tp, result.template get<0>(), result.template get<1>(), side_calc);
std::pair<operation_type, operation_type>
operations = operations_of_equal(side_calc);
// TODO: must the above be calculated?
// wouldn't it be enough to check if segments are collinear?
if ( tp.both(operation_continue) )
if ( operations_both(operations, operation_continue) )
{
// THIS IS WRT THE ORIGINAL SEGMENTS! NOT THE ONES ABOVE!
bool opposite = result.template get<1>().opposite;
@@ -429,7 +428,7 @@ struct get_turn_info_for_endpoint
}
else
{
BOOST_ASSERT(tp.combination(operation_intersection, operation_union));
BOOST_ASSERT(operations_combination(operations, operation_intersection, operation_union));
//op1 = operation_union;
//op2 = operation_union;
}
@@ -460,14 +459,13 @@ struct get_turn_info_for_endpoint
side_calculator<Point1, Point2> side_calc(i2_conv, j1, i1, i2, j2, k2);
TurnInfo tp = tp_model;
equal<TurnInfo>::apply(i2_conv, j1, i1, i2, j2, k2,
tp, result.template get<0>(), result.template get<1>(), side_calc);
std::pair<operation_type, operation_type>
operations = operations_of_equal(side_calc);
// TODO: must the above be calculated?
// wouldn't it be enough to check if segments are collinear?
if ( tp.both(operation_continue) )
if ( operations_both(operations, operation_continue) )
{
// THIS IS WRT THE ORIGINAL SEGMENTS! NOT THE ONES ABOVE!
bool second_going_out = result.template get<0>().count > 1;
@@ -477,7 +475,7 @@ struct get_turn_info_for_endpoint
}
else
{
BOOST_ASSERT(tp.combination(operation_intersection, operation_union));
BOOST_ASSERT(operations_combination(operations, operation_intersection, operation_union));
//op1 = operation_blocked;
//op2 = operation_union;
}
@@ -552,6 +550,66 @@ struct get_turn_info_for_endpoint
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
*out++ = tp;
}
template <typename SidePolicy>
static inline std::pair<operation_type, operation_type> operations_of_equal(SidePolicy const& side)
{
int const side_pk_q2 = side.pk_wrt_q2();
int const side_pk_p = side.pk_wrt_p1();
int const side_qk_p = side.qk_wrt_p1();
// If pk is collinear with qj-qk, they continue collinearly.
// This can be on either side of p1 (== q1), or collinear
// The second condition checks if they do not continue
// oppositely
if ( side_pk_q2 == 0 && side_pk_p == side_qk_p )
{
return std::make_pair(operation_continue, operation_continue);
}
// If they turn to same side (not opposite sides)
if ( ! base_turn_handler::opposite(side_pk_p, side_qk_p) )
{
int const side_pk_q2 = side.pk_wrt_q2();
// If pk is left of q2 or collinear: p: union, q: intersection
if ( side_pk_q2 != -1 )
{
return std::make_pair(operation_union, operation_intersection);
}
else
{
return std::make_pair(operation_intersection, operation_union);
}
}
else
{
// They turn opposite sides. If p turns left (or collinear),
// p: union, q: intersection
if ( side_pk_p != -1 )
{
return std::make_pair(operation_union, operation_intersection);
}
else
{
return std::make_pair(operation_intersection, operation_union);
}
}
}
static inline bool operations_both(
std::pair<operation_type, operation_type> const& operations,
operation_type const op)
{
return operations.first == op && operations.second == op;
}
static inline bool operations_combination(
std::pair<operation_type, operation_type> const& operations,
operation_type const op1, operation_type const op2)
{
return ( operations.first == op1 && operations.second == op2 )
|| ( operations.first == op2 && operations.second == op1 );
}
};
}} // namespace detail::overlay

View File

@@ -458,8 +458,11 @@ struct get_turn_info_linear_areal
{
side_calculator<Point1, Point2> side_calc(qi_conv, pi, pj, qi, qj, qk);
equal<TurnInfo>::apply(qi_conv, pi, pj, qi, qj, qk,
tp, result.template get<0>(), result.template get<1>(), side_calc);
std::pair<operation_type, operation_type>
operations = get_info_e::operations_of_equal(side_calc);
tp.operations[0].operation = operations.first;
tp.operations[1].operation = operations.second;
replaced_method = method_touch;
}
@@ -471,9 +474,11 @@ struct get_turn_info_linear_areal
side_calculator<Point1, Point2> side_calc(qi_conv, pi, pj, qi, pi_conv, qj);
// Collinear, but similar thus handled as equal
equal<TurnInfo>::apply(qi_conv, pi, pj, qi, pi_conv, qj,
tp, result.template get<0>(), result.template get<1>(), side_calc);
std::pair<operation_type, operation_type>
operations = get_info_e::operations_of_equal(side_calc);
tp.operations[0].operation = operations.first;
tp.operations[1].operation = operations.second;
}
replacer_of_method_and_operations_ec<true> replacer(replaced_method);
@@ -519,8 +524,11 @@ struct get_turn_info_linear_areal
geometry::convert(qi, qi_conv);
side_calculator<Point1, Point2> side_calc(qi_conv, pj, pi, qi, qj, qk);
equal<TurnInfo>::apply(qi_conv, pj, pi, qi, qj, qk,
tp, result.template get<0>(), result.template get<1>(), side_calc);
std::pair<operation_type, operation_type>
operations = get_info_e::operations_of_equal(side_calc);
tp.operations[0].operation = operations.first;
tp.operations[1].operation = operations.second;
replacer_of_method_and_operations_ec<false> replacer(method_none);
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);