mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-11 11:52:11 +00:00
get_turns(L,A) - fixed turns generation for endpoints of collinear front/back segments, added some tests
This commit is contained in:
@@ -166,7 +166,7 @@ struct get_turn_info_linear_areal
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
|
||||
replacer_of_method_and_operations_ec replacer(method_touch);
|
||||
replacer_of_method_and_operations_ec<false> replacer(method_touch);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
@@ -201,7 +201,7 @@ struct get_turn_info_linear_areal
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
|
||||
replacer_of_method_and_operations_ec replacer(method_touch);
|
||||
replacer_of_method_and_operations_ec<false> replacer(method_touch);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
}
|
||||
else
|
||||
@@ -209,7 +209,7 @@ struct get_turn_info_linear_areal
|
||||
collinear<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
|
||||
replacer_of_method_and_operations_ec replacer(method_touch_interior);
|
||||
replacer_of_method_and_operations_ec<false> replacer(method_touch_interior);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
}
|
||||
|
||||
@@ -218,8 +218,8 @@ struct get_turn_info_linear_areal
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this always 'm' ?
|
||||
replacer_of_method_and_operations_ec replacer(method_touch_interior);
|
||||
// Is this always 'm' ?
|
||||
replacer_of_method_and_operations_ec<false> replacer(method_touch_interior);
|
||||
|
||||
collinear_opposite
|
||||
<
|
||||
@@ -274,6 +274,7 @@ struct get_turn_info_linear_areal
|
||||
op1 = operation_union;
|
||||
}
|
||||
|
||||
template <bool IsFront>
|
||||
class replacer_of_method_and_operations_ec
|
||||
{
|
||||
public:
|
||||
@@ -286,8 +287,9 @@ struct get_turn_info_linear_areal
|
||||
operation_type & op1) const
|
||||
{
|
||||
// NOTE: probably only if methods are WRT IPs, not segments!
|
||||
if ( op0 == operation_intersection || op0 == operation_union
|
||||
|| op1 == operation_intersection || op1 == operation_union )
|
||||
if ( IsFront
|
||||
|| op0 == operation_intersection || op0 == operation_union
|
||||
|| op1 == operation_intersection || op1 == operation_union )
|
||||
{
|
||||
method = m_method;
|
||||
}
|
||||
@@ -331,19 +333,19 @@ struct get_turn_info_linear_areal
|
||||
namespace ov = overlay;
|
||||
typedef ov::get_turn_info_for_endpoint<AssignPolicy, EnableFirst, EnableLast> get_info_e;
|
||||
|
||||
std::size_t ip_count = result.template get<0>().count;
|
||||
const std::size_t ip_count = result.template get<0>().count;
|
||||
// no intersection points
|
||||
if ( ip_count == 0 )
|
||||
return false;
|
||||
|
||||
int segment_index0 = tp_model.operations[0].seg_id.segment_index;
|
||||
int segment_index1 = tp_model.operations[1].seg_id.segment_index;
|
||||
const int segment_index0 = tp_model.operations[0].seg_id.segment_index;
|
||||
const int segment_index1 = tp_model.operations[1].seg_id.segment_index;
|
||||
BOOST_ASSERT(segment_index0 >= 0 && segment_index1 >= 0);
|
||||
|
||||
bool is_p_first = segment_index0 == 0;
|
||||
bool is_q_first = segment_index1 == 0; // not used
|
||||
bool is_p_last = static_cast<std::size_t>(segment_index0) + 1 == p_segments_count;
|
||||
bool is_q_last = static_cast<std::size_t>(segment_index1) + 1 == q_segments_count; // not used
|
||||
const bool is_p_first = segment_index0 == 0;
|
||||
const bool is_q_first = segment_index1 == 0; // not used
|
||||
const bool is_p_last = static_cast<std::size_t>(segment_index0) + 1 == p_segments_count;
|
||||
const bool is_q_last = static_cast<std::size_t>(segment_index1) + 1 == q_segments_count; // not used
|
||||
|
||||
if ( !is_p_first && !is_p_last )
|
||||
return false;
|
||||
@@ -355,14 +357,14 @@ struct get_turn_info_linear_areal
|
||||
bool p0i, p0j, q0i, q0j; // assign false?
|
||||
bool p1i, p1j, q1i, q1j; // assign false?
|
||||
|
||||
bool opposite = result.template get<1>().opposite;
|
||||
bool same_dirs = result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0;
|
||||
const bool opposite = result.template get<1>().opposite;
|
||||
const bool same_dirs = result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0;
|
||||
|
||||
{
|
||||
int p_how = result.template get<1>().how_a;
|
||||
int q_how = result.template get<1>().how_b;
|
||||
int p_arrival = result.template get<1>().arrival[0];
|
||||
int q_arrival = result.template get<1>().arrival[1];
|
||||
const int p_how = result.template get<1>().how_a;
|
||||
const int q_how = result.template get<1>().how_b;
|
||||
const int p_arrival = result.template get<1>().arrival[0];
|
||||
const int q_arrival = result.template get<1>().arrival[1];
|
||||
|
||||
get_info_e::handle_segment(
|
||||
is_p_first, is_p_last, p_how, p_arrival,
|
||||
@@ -420,7 +422,7 @@ struct get_turn_info_linear_areal
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
}
|
||||
|
||||
replacer_of_method_and_operations_ec replacer(replaced_method);
|
||||
replacer_of_method_and_operations_ec<true> replacer(replaced_method);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
// equals<> or collinear<> will assign the second point,
|
||||
@@ -434,10 +436,10 @@ struct get_turn_info_linear_areal
|
||||
// ANALYSE AND ASSIGN LAST
|
||||
|
||||
// IP on the first point of Linear Geometry
|
||||
if ( EnableLast && is_p_last && p0j && !q0i ) // !q0i prevents duplication
|
||||
if ( EnableLast && is_p_last && ( ip_count > 1 ? p1j : p0j ) && !q0i && !q1i ) // !q0i && !q1i prevents duplication
|
||||
{
|
||||
TurnInfo tp = tp_model;
|
||||
tp.method = q0j ? method_touch : method_touch_interior;
|
||||
tp.method = ( ip_count > 1 ? q1j : q0j ) ? method_touch : method_touch_interior;
|
||||
tp.operations[0].operation = operation_blocked;
|
||||
tp.operations[1].operation = operation_union;
|
||||
tp.operations[0].position = position_back;
|
||||
@@ -445,7 +447,8 @@ struct get_turn_info_linear_areal
|
||||
|
||||
// equals<> or collinear<> will assign the second point,
|
||||
// we'd like to assign the first one
|
||||
geometry::convert(result.template get<0>().intersections[0], tp.point);
|
||||
std::size_t ip_index = ip_count > 1 ? 1 : 0;
|
||||
geometry::convert(result.template get<0>().intersections[ip_index], tp.point);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
*out++ = tp;
|
||||
|
||||
@@ -32,6 +32,24 @@ void test_all()
|
||||
typedef bg::model::linestring<pt> ls;
|
||||
typedef bg::model::polygon<pt> poly;
|
||||
|
||||
test_geometry<ls, poly>("LINESTRING(15 5,24 5,20 2,19 0,13 -4,1 0,10 0,13 3,15 7,16 10,10 10,8 10,4 6,2 8,1 10)",
|
||||
"POLYGON((0 0,5 5,0 10,20 10,20 2,19 0,0 0)(10 3,15 3,15 7,10 7,10 3))",
|
||||
expected("miu")("iuu")("tcu")("tuu")("mcu")("miu")("muu")("tiu")("mcu")("miu")("mcu")("miu")("mxu").vec);
|
||||
|
||||
test_geometry<ls, poly>("LINESTRING(5 0,5 5,10 5)", "POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"miu", "mxu");
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,5 5,10 0)", "POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"tiu", "txu");
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,5 0,5 5,10 5,10 0)", "POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
expected("tcu")("miu")("mcu")("txu").vec);
|
||||
test_geometry<ls, poly>("LINESTRING(10 0,5 0,5 5,10 5,10 10)", "POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
expected("tcu")("miu")("mcu")("txu").vec);
|
||||
|
||||
test_geometry<ls, poly>("LINESTRING(0 0,10 0,10 10)",
|
||||
"POLYGON((0 0,5 5,0 10,20 10,20 2,19 0,0 0)(10 3,15 3,15 7,10 7,10 3))",
|
||||
expected("tcu")("miu")("mcu")("miu")("mxu").vec);
|
||||
|
||||
|
||||
to_svg<ls, poly>("LINESTRING(15 5,24 5,20 2,19 0,13 -4,1 0,10 0,13 3,15 7,16 10,10 10,8 10,4 6,2 8,1 10)",
|
||||
"POLYGON((0 0,5 5,0 10,20 10,20 2,19 0,0 0)(10 3,15 3,15 7,10 7,10 3))",
|
||||
"ls_poly1.svg");
|
||||
|
||||
Reference in New Issue
Block a user