mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-21 03:02:10 +00:00
[get_turns] Refactor get_turns for L/L and L/A.
This change prevents duplication and decreases the number of parameters that must be passed to various functions and makes the code more readable. Enclose parts of the code used in both implementations in one class - intersection_info. Move there IntersectionsResult, sides_calculator, spikes checks. Use this class in get_turn_info_linear_*. Provide convenient i_info() and d_info() to allow replacing result.template get<0>() and result.template get<1>() calls.
This commit is contained in:
@@ -38,96 +38,116 @@ struct turn_operation_linear
|
||||
bool is_collinear; // valid only for Linear geometry
|
||||
};
|
||||
|
||||
// IS_SPIKE
|
||||
|
||||
template <typename Point, typename RobustPolicy>
|
||||
inline bool is_spike_of_collinear(model::referring_segment<Point const> const& s1,
|
||||
model::referring_segment<Point const> const& s2,
|
||||
RobustPolicy const& robust_policy)
|
||||
template <typename Point1, typename Point2, typename TurnPoint, typename RobustPolicy>
|
||||
class intersection_info
|
||||
{
|
||||
typedef strategy_intersection
|
||||
typedef typename strategy_intersection
|
||||
<
|
||||
typename cs_tag<Point>::type, Point, Point, Point, RobustPolicy
|
||||
> si;
|
||||
|
||||
typedef typename si::segment_intersection_strategy_type strategy;
|
||||
|
||||
typename strategy::return_type result = strategy::apply(s1, s2, robust_policy);
|
||||
|
||||
return result.template get<0>().count == 2;
|
||||
}
|
||||
typename cs_tag<TurnPoint>::type,
|
||||
Point1,
|
||||
Point2,
|
||||
TurnPoint,
|
||||
RobustPolicy
|
||||
>::segment_intersection_strategy_type strategy;
|
||||
|
||||
template <typename Point1, typename Point2, typename RobustPolicy>
|
||||
inline bool is_spike_p(side_calculator<Point1, Point2> const& side_calc,
|
||||
model::referring_segment<Point1 const> const& p1,
|
||||
model::referring_segment<Point1 const> const& p2,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
if ( side_calc.pk_wrt_p1() == 0 )
|
||||
{
|
||||
int const qk_p1 = side_calc.qk_wrt_p1();
|
||||
int const qk_p2 = side_calc.qk_wrt_p2();
|
||||
|
||||
if ( qk_p1 == -qk_p2 )
|
||||
{
|
||||
if ( qk_p1 == 0 )
|
||||
{
|
||||
return is_spike_of_collinear(p1, p2, robust_policy);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Point1, typename Point2, typename RobustPolicy>
|
||||
inline bool is_spike_q(side_calculator<Point1, Point2> const& side_calc,
|
||||
model::referring_segment<Point2 const> const& q1,
|
||||
model::referring_segment<Point2 const> const& q2,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
if ( side_calc.qk_wrt_q1() == 0 )
|
||||
{
|
||||
int const pk_q1 = side_calc.pk_wrt_q1();
|
||||
int const pk_q2 = side_calc.pk_wrt_q2();
|
||||
|
||||
if ( pk_q1 == -pk_q2 )
|
||||
{
|
||||
if ( pk_q1 == 0 )
|
||||
{
|
||||
return is_spike_of_collinear(q1, q2, robust_policy);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Point1, typename Point2, typename RobustPolicy>
|
||||
inline bool is_spike_p(Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
public:
|
||||
typedef model::referring_segment<Point1 const> segment_type1;
|
||||
segment_type1 p1(pi, pj), p2(pj, pk);
|
||||
side_calculator<Point1, Point2> side_calc(pi, pj, pk, qi, qj, qk);
|
||||
return is_spike_p(side_calc, p1, p2, robust_policy);
|
||||
}
|
||||
|
||||
template <typename Point1, typename Point2, typename RobustPolicy>
|
||||
inline bool is_spike_q(Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
RobustPolicy const& robust_policy)
|
||||
{
|
||||
typedef model::referring_segment<Point2 const> segment_type2;
|
||||
segment_type2 q1(qi, qj), q2(qj, qk);
|
||||
side_calculator<Point1, Point2> side_calc(pi, pj, pk, qi, qj, qk);
|
||||
return is_spike_q(side_calc, q1, q2, robust_policy);
|
||||
}
|
||||
typedef side_calculator<Point1, Point2> side_calculator_type;
|
||||
|
||||
typedef typename strategy::return_type result_type;
|
||||
typedef typename boost::tuples::element<0, result_type>::type i_info_type; // intersection_info
|
||||
typedef typename boost::tuples::element<1, result_type>::type d_info_type; // dir_info
|
||||
|
||||
intersection_info(Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
Point2 const& qi, Point2 const& qj, Point2 const& qk,
|
||||
RobustPolicy const& robust_policy)
|
||||
: m_result(strategy::apply(segment_type1(pi, pj),
|
||||
segment_type2(qi, qj),
|
||||
robust_policy))
|
||||
, m_side_calc(pi, pj, pk, qi, qj, qk)
|
||||
, m_robust_policy(robust_policy)
|
||||
{}
|
||||
|
||||
inline Point1 const& pi() const { return m_side_calc.m_pi; }
|
||||
inline Point1 const& pj() const { return m_side_calc.m_pj; }
|
||||
inline Point1 const& pk() const { return m_side_calc.m_pk; }
|
||||
|
||||
inline Point2 const& qi() const { return m_side_calc.m_qi; }
|
||||
inline Point2 const& qj() const { return m_side_calc.m_qj; }
|
||||
inline Point2 const& qk() const { return m_side_calc.m_qk; }
|
||||
|
||||
inline side_calculator_type const& sides() const { return m_side_calc; }
|
||||
inline result_type const& result() const { return m_result; }
|
||||
inline i_info_type const& i_info() const { return m_result.template get<0>(); }
|
||||
inline d_info_type const& d_info() const { return m_result.template get<1>(); }
|
||||
|
||||
inline bool is_spike_p() const
|
||||
{
|
||||
if ( m_side_calc.pk_wrt_p1() == 0 )
|
||||
{
|
||||
int const qk_p1 = m_side_calc.qk_wrt_p1();
|
||||
int const qk_p2 = m_side_calc.qk_wrt_p2();
|
||||
|
||||
if ( qk_p1 == -qk_p2 )
|
||||
{
|
||||
if ( qk_p1 == 0 )
|
||||
{
|
||||
return is_spike_of_collinear(segment_type1(pi(), pj()),
|
||||
segment_type1(pj(), pk()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool is_spike_q() const
|
||||
{
|
||||
if ( m_side_calc.qk_wrt_q1() == 0 )
|
||||
{
|
||||
int const pk_q1 = m_side_calc.pk_wrt_q1();
|
||||
int const pk_q2 = m_side_calc.pk_wrt_q2();
|
||||
|
||||
if ( pk_q1 == -pk_q2 )
|
||||
{
|
||||
if ( pk_q1 == 0 )
|
||||
{
|
||||
return is_spike_of_collinear(segment_type2(qi(), qj()),
|
||||
segment_type2(qj(), qk()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Point>
|
||||
inline bool is_spike_of_collinear(
|
||||
model::referring_segment<Point const> const& s1,
|
||||
model::referring_segment<Point const> const& s2) const
|
||||
{
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<Point>::type, Point, Point, Point, RobustPolicy
|
||||
> si;
|
||||
|
||||
typedef typename si::segment_intersection_strategy_type strategy;
|
||||
|
||||
typename strategy::return_type result = strategy::apply(s1, s2, m_robust_policy);
|
||||
|
||||
return result.template get<0>().count == 2;
|
||||
}
|
||||
|
||||
result_type m_result;
|
||||
side_calculator_type m_side_calc;
|
||||
RobustPolicy const& m_robust_policy;
|
||||
};
|
||||
|
||||
// SEGMENT_INTERSECTION RESULT
|
||||
|
||||
@@ -335,8 +355,7 @@ struct get_turn_info_for_endpoint
|
||||
template<typename Point1,
|
||||
typename Point2,
|
||||
typename TurnInfo,
|
||||
typename IntersectionResult,
|
||||
typename RobustPolicy,
|
||||
typename IntersectionInfo,
|
||||
typename OutputIterator
|
||||
>
|
||||
static inline bool apply(Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
@@ -344,12 +363,11 @@ struct get_turn_info_for_endpoint
|
||||
bool is_p_first, bool is_p_last,
|
||||
bool is_q_first, bool is_q_last,
|
||||
TurnInfo const& tp_model,
|
||||
IntersectionResult const& result,
|
||||
RobustPolicy const& robust_policy,
|
||||
IntersectionInfo const& inters,
|
||||
method_type /*method*/,
|
||||
OutputIterator out)
|
||||
{
|
||||
std::size_t ip_count = result.template get<0>().count;
|
||||
std::size_t ip_count = inters.i_info().count;
|
||||
// no intersection points
|
||||
if ( ip_count == 0 )
|
||||
return false;
|
||||
@@ -361,17 +379,16 @@ struct get_turn_info_for_endpoint
|
||||
if ( !is_p_first && !is_p_last && !is_q_first && !is_q_last )
|
||||
return false;
|
||||
|
||||
linear_intersections intersections(pi, qi, result, is_p_last, is_q_last);
|
||||
linear_intersections intersections(pi, qi, inters.result(), is_p_last, is_q_last);
|
||||
|
||||
bool append0_last
|
||||
= analyse_segment_and_assign_ip(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
intersections.template get<0>(),
|
||||
tp_model, result, 0,
|
||||
robust_policy, out);
|
||||
tp_model, inters, 0, out);
|
||||
|
||||
// NOTE: opposite && ip_count == 1 may be true!
|
||||
bool opposite = result.template get<1>().opposite;
|
||||
bool opposite = inters.d_info().opposite;
|
||||
|
||||
// don't ignore only for collinear opposite
|
||||
bool result_ignore_ip0 = append0_last && ( ip_count == 1 || !opposite );
|
||||
@@ -383,8 +400,7 @@ struct get_turn_info_for_endpoint
|
||||
= analyse_segment_and_assign_ip(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
intersections.template get<1>(),
|
||||
tp_model, result, 1,
|
||||
robust_policy, out);
|
||||
tp_model, inters, 1, out);
|
||||
|
||||
// don't ignore only for collinear opposite
|
||||
bool result_ignore_ip1 = append1_last && !opposite /*&& ip_count == 2*/;
|
||||
@@ -395,8 +411,7 @@ struct get_turn_info_for_endpoint
|
||||
template <typename Point1,
|
||||
typename Point2,
|
||||
typename TurnInfo,
|
||||
typename IntersectionResult,
|
||||
typename RobustPolicy,
|
||||
typename IntersectionInfo,
|
||||
typename OutputIterator>
|
||||
static inline
|
||||
bool analyse_segment_and_assign_ip(Point1 const& pi, Point1 const& pj, Point1 const& pk,
|
||||
@@ -405,9 +420,8 @@ struct get_turn_info_for_endpoint
|
||||
bool is_q_first, bool is_q_last,
|
||||
linear_intersections::ip_info const& ip_info,
|
||||
TurnInfo const& tp_model,
|
||||
IntersectionResult const& result,
|
||||
IntersectionInfo const& inters,
|
||||
int ip_index,
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out)
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS_LINEAR_LINEAR
|
||||
@@ -437,14 +451,16 @@ struct get_turn_info_for_endpoint
|
||||
is_p_first_ip, is_p_last_ip,
|
||||
is_q_first_ip, is_q_last_ip,
|
||||
ip_info.is_qi, ip_info.is_qj,
|
||||
tp_model, result, ip_index, p_operation, q_operation);
|
||||
tp_model, inters.result(), ip_index,
|
||||
p_operation, q_operation);
|
||||
if ( !handled )
|
||||
{
|
||||
handle_internal(qi, qj, qk, pi, pj, pk,
|
||||
is_q_first_ip, is_q_last_ip,
|
||||
is_p_first_ip, is_p_last_ip,
|
||||
ip_info.is_pi, ip_info.is_pj,
|
||||
tp_model, result, ip_index, q_operation, p_operation);
|
||||
tp_model, inters.result(), ip_index,
|
||||
q_operation, p_operation);
|
||||
}
|
||||
|
||||
if ( p_operation != operation_none )
|
||||
@@ -458,28 +474,28 @@ struct get_turn_info_for_endpoint
|
||||
|
||||
// P is spike and should be handled
|
||||
if ( !is_p_last && ip_info.is_pj
|
||||
&& result.template get<0>().count == 2
|
||||
&& is_spike_p(pi, pj, pk, qi, qj, qk, robust_policy) )
|
||||
&& inters.i_info().count == 2
|
||||
&& inters.is_spike_p() )
|
||||
{
|
||||
assign(pi, qi, result, ip_index, method, operation_blocked, q_operation,
|
||||
assign(pi, qi, inters.result(), ip_index, method, operation_blocked, q_operation,
|
||||
p_pos, q_pos, tp_model, out);
|
||||
assign(pi, qi, result, ip_index, method, operation_intersection, q_operation,
|
||||
assign(pi, qi, inters.result(), ip_index, method, operation_intersection, q_operation,
|
||||
p_pos, q_pos, tp_model, out);
|
||||
}
|
||||
// Q is spike and should be handled
|
||||
else if ( !is_q_last && ip_info.is_qj
|
||||
&& result.template get<0>().count == 2
|
||||
&& is_spike_q(pi, pj, pk, qi, qj, qk, robust_policy) )
|
||||
&& inters.i_info().count == 2
|
||||
&& inters.is_spike_q() )
|
||||
{
|
||||
assign(pi, qi, result, ip_index, method, p_operation, operation_blocked,
|
||||
assign(pi, qi, inters.result(), ip_index, method, p_operation, operation_blocked,
|
||||
p_pos, q_pos, tp_model, out);
|
||||
assign(pi, qi, result, ip_index, method, p_operation, operation_intersection,
|
||||
assign(pi, qi, inters.result(), ip_index, method, p_operation, operation_intersection,
|
||||
p_pos, q_pos, tp_model, out);
|
||||
}
|
||||
// no spikes
|
||||
else
|
||||
{
|
||||
assign(pi, qi, result, ip_index, method, p_operation, q_operation,
|
||||
assign(pi, qi, inters.result(), ip_index, method, p_operation, q_operation,
|
||||
p_pos, q_pos, tp_model, out);
|
||||
}
|
||||
}
|
||||
@@ -498,12 +514,9 @@ struct get_turn_info_for_endpoint
|
||||
>
|
||||
static inline bool handle_internal(Point1 const& i1, Point1 const& j1, Point1 const& /*k1*/,
|
||||
Point2 const& i2, Point2 const& j2, Point2 const& k2,
|
||||
bool first1, bool last1,
|
||||
bool first2, bool last2,
|
||||
bool ip_i2, bool ip_j2,
|
||||
TurnInfo const& tp_model,
|
||||
IntersectionResult const& result,
|
||||
int ip_index,
|
||||
bool first1, bool last1, bool first2, bool last2,
|
||||
bool ip_i2, bool ip_j2, TurnInfo const& tp_model,
|
||||
IntersectionResult const& result, int ip_index,
|
||||
operation_type & op1, operation_type & op2)
|
||||
{
|
||||
boost::ignore_unused_variable_warning(ip_index);
|
||||
|
||||
@@ -47,27 +47,10 @@ struct get_turn_info_linear_areal
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out)
|
||||
{
|
||||
typedef model::referring_segment<Point1 const> segment_type1;
|
||||
typedef model::referring_segment<Point2 const> segment_type2;
|
||||
segment_type1 p1(pi, pj), p2(pj, pk);
|
||||
segment_type2 q1(qi, qj), q2(qj, qk);
|
||||
intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
|
||||
inters(pi, pj, pk, qi, qj, qk, robust_policy);
|
||||
|
||||
side_calculator<Point1, Point2> side_calc(pi, pj, pk, qi, qj, qk);
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<typename TurnInfo::point_type>::type,
|
||||
Point1,
|
||||
Point2,
|
||||
typename TurnInfo::point_type,
|
||||
RobustPolicy
|
||||
> si;
|
||||
|
||||
typedef typename si::segment_intersection_strategy_type strategy;
|
||||
|
||||
typename strategy::return_type result = strategy::apply(p1, q1, robust_policy);
|
||||
|
||||
char const method = result.template get<1>().how;
|
||||
char const method = inters.d_info().how;
|
||||
|
||||
// Copy, to copy possibly extended fields
|
||||
TurnInfo tp = tp_model;
|
||||
@@ -81,7 +64,7 @@ struct get_turn_info_linear_areal
|
||||
get_turn_info_for_endpoint<true, true>(
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_none, out);
|
||||
tp_model, inters.result(), method_none, out);
|
||||
break;
|
||||
|
||||
case 'd' : // disjoint: never do anything
|
||||
@@ -92,7 +75,7 @@ struct get_turn_info_linear_areal
|
||||
if ( get_turn_info_for_endpoint<false, true>(
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_touch_interior, out) )
|
||||
tp_model, inters.result(), method_touch_interior, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -104,18 +87,18 @@ struct get_turn_info_linear_areal
|
||||
> policy;
|
||||
|
||||
// If Q (1) arrives (1)
|
||||
if (result.template get<1>().arrival[1] == 1)
|
||||
if ( inters.d_info().arrival[1] == 1 )
|
||||
{
|
||||
policy::template apply<0>(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(),
|
||||
side_calc);
|
||||
tp, inters.i_info(), inters.d_info(),
|
||||
inters.sides());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Swap p/q
|
||||
side_calculator<Point2, Point1> swapped_side_calc(qi, qj, qk, pi, pj, pk);
|
||||
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
|
||||
tp, result.template get<0>(), result.template get<1>(),
|
||||
tp, inters.i_info(), inters.d_info(),
|
||||
swapped_side_calc);
|
||||
}
|
||||
|
||||
@@ -130,10 +113,9 @@ struct get_turn_info_linear_areal
|
||||
|
||||
// this function assumes that 'u' must be set for a spike
|
||||
calculate_spike_operation(tp.operations[0].operation,
|
||||
side_calc, p1, p2,
|
||||
is_p_last, robust_policy);
|
||||
inters, is_p_last);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
|
||||
*out++ = tp;
|
||||
}
|
||||
@@ -142,11 +124,11 @@ struct get_turn_info_linear_areal
|
||||
case 'i' :
|
||||
{
|
||||
crosses<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
tp, inters.i_info(), inters.d_info());
|
||||
|
||||
replace_operations_i(tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -156,14 +138,14 @@ struct get_turn_info_linear_areal
|
||||
if ( get_turn_info_for_endpoint<false, true>(
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_touch, out) )
|
||||
tp_model, inters.result(), method_touch, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
touch<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
if ( tp.operations[1].operation == operation_blocked )
|
||||
{
|
||||
@@ -177,19 +159,15 @@ struct get_turn_info_linear_areal
|
||||
// this function assumes that 'u' must be set for a spike
|
||||
bool ignore_spike
|
||||
= calculate_spike_operation(tp.operations[0].operation,
|
||||
side_calc, p1, p2,
|
||||
is_p_last, robust_policy);
|
||||
inters, is_p_last);
|
||||
|
||||
// TODO: move this into the append_xxx and call for each turn?
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
|
||||
if ( ! handle_spikes
|
||||
|| ignore_spike
|
||||
|| ! append_opposite_spikes<append_touches>( // for 'i' or 'c'
|
||||
tp, result, side_calc,
|
||||
p1, p2, q1, q2,
|
||||
is_p_last, is_q_last,
|
||||
robust_policy, out) )
|
||||
tp, inters, is_p_last, is_q_last, out) )
|
||||
{
|
||||
*out++ = tp;
|
||||
}
|
||||
@@ -201,7 +179,7 @@ struct get_turn_info_linear_areal
|
||||
if ( get_turn_info_for_endpoint<true, true>(
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_equal, out) )
|
||||
tp_model, inters.result(), method_equal, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -209,26 +187,23 @@ struct get_turn_info_linear_areal
|
||||
{
|
||||
tp.operations[0].is_collinear = true;
|
||||
|
||||
if ( ! result.template get<1>().opposite )
|
||||
if ( ! inters.d_info().opposite )
|
||||
{
|
||||
// Both equal
|
||||
// or collinear-and-ending at intersection point
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
replacer_of_method_and_operations_ec<false> replacer(method_touch);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
// TODO: move this into the append_xxx and call for each turn?
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
|
||||
// conditionally handle spikes
|
||||
if ( ! handle_spikes
|
||||
|| ! append_collinear_spikes(
|
||||
tp, side_calc, p1, p2, q1, q2,
|
||||
is_p_last, is_q_last,
|
||||
method_touch, append_equal,
|
||||
robust_policy, out) )
|
||||
|| ! append_collinear_spikes(tp, inters, is_p_last, is_q_last,
|
||||
method_touch, append_equal, out) )
|
||||
{
|
||||
*out++ = tp; // no spikes
|
||||
}
|
||||
@@ -240,7 +215,7 @@ struct get_turn_info_linear_areal
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, qi,
|
||||
tp, out, result.template get<0>(), result.template get<1>());
|
||||
tp, out, inters.i_info(), inters.d_info());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,7 +226,7 @@ struct get_turn_info_linear_areal
|
||||
if ( get_turn_info_for_endpoint<true, true>(
|
||||
pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, method_collinear, out) )
|
||||
tp_model, inters.result(), method_collinear, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -259,16 +234,16 @@ struct get_turn_info_linear_areal
|
||||
{
|
||||
tp.operations[0].is_collinear = true;
|
||||
|
||||
if (! result.template get<1>().opposite)
|
||||
if ( ! inters.d_info().opposite )
|
||||
{
|
||||
method_type method_replace = method_touch_interior;
|
||||
append_version_c version = append_collinear;
|
||||
|
||||
if (result.template get<1>().arrival[0] == 0)
|
||||
if ( inters.d_info().arrival[0] == 0 )
|
||||
{
|
||||
// Collinear, but similar thus handled as equal
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
method_replace = method_touch;
|
||||
version = append_equal;
|
||||
@@ -276,7 +251,7 @@ struct get_turn_info_linear_areal
|
||||
else
|
||||
{
|
||||
collinear<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
//method_replace = method_touch_interior;
|
||||
//version = append_collinear;
|
||||
@@ -286,15 +261,12 @@ struct get_turn_info_linear_areal
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
// TODO: move this into the append_xxx and call for each turn?
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
|
||||
// conditionally handle spikes
|
||||
if ( ! handle_spikes
|
||||
|| ! append_collinear_spikes(
|
||||
tp, side_calc, p1, p2, q1, q2,
|
||||
is_p_last, is_q_last,
|
||||
method_replace, version,
|
||||
robust_policy, out) )
|
||||
|| ! append_collinear_spikes(tp, inters, is_p_last, is_q_last,
|
||||
method_replace, version, out) )
|
||||
{
|
||||
// no spikes
|
||||
*out++ = tp;
|
||||
@@ -309,10 +281,7 @@ struct get_turn_info_linear_areal
|
||||
if ( handle_spikes )
|
||||
{
|
||||
append_opposite_spikes<append_collinear_opposite>(
|
||||
tp, result, side_calc,
|
||||
p1, p2, q1, q2,
|
||||
is_p_last, is_q_last,
|
||||
robust_policy, out);
|
||||
tp, inters, is_p_last, is_q_last, out);
|
||||
}
|
||||
|
||||
// TODO: ignore for spikes?
|
||||
@@ -324,8 +293,8 @@ struct get_turn_info_linear_areal
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, out, result.template get<0>(), result.template get<1>(), side_calc,
|
||||
replacer);
|
||||
tp, out, inters.i_info(), inters.d_info(),
|
||||
inters.sides(), replacer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -335,7 +304,7 @@ struct get_turn_info_linear_areal
|
||||
// degenerate points
|
||||
if (AssignPolicy::include_degenerate)
|
||||
{
|
||||
only_convert::apply(tp, result.template get<0>());
|
||||
only_convert::apply(tp, inters.i_info());
|
||||
|
||||
if ( is_p_first
|
||||
&& equals::equals_point_point(pi, tp.point) )
|
||||
@@ -349,7 +318,7 @@ struct get_turn_info_linear_areal
|
||||
}
|
||||
// tp.operations[1].position = position_middle;
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
@@ -370,24 +339,19 @@ struct get_turn_info_linear_areal
|
||||
}
|
||||
|
||||
template <typename Operation,
|
||||
typename SideCalc,
|
||||
typename PSegment,
|
||||
typename RobustPolicy>
|
||||
typename IntersectionInfo>
|
||||
static inline bool calculate_spike_operation(Operation & op,
|
||||
SideCalc const& side_calc,
|
||||
PSegment const& p1,
|
||||
PSegment const& p2,
|
||||
bool is_p_last,
|
||||
RobustPolicy const& robust_policy)
|
||||
IntersectionInfo const& inters,
|
||||
bool is_p_last)
|
||||
{
|
||||
bool is_p_spike = op == operation_union
|
||||
&& ! is_p_last
|
||||
&& is_spike_p(side_calc, p1, p2, robust_policy);
|
||||
&& inters.is_spike_p();
|
||||
|
||||
// we don't know where the spike is going since for both directions 'u' is set
|
||||
if ( is_p_spike )
|
||||
{
|
||||
if ( side_calc.pk_wrt_q1() < 0 && side_calc.pk_wrt_q2() < 0 )
|
||||
if ( inters.sides().pk_wrt_q1() < 0 && inters.sides().pk_wrt_q2() < 0 )
|
||||
{
|
||||
op = operation_intersection;
|
||||
return true;
|
||||
@@ -400,18 +364,13 @@ struct get_turn_info_linear_areal
|
||||
enum append_version_c { append_equal, append_collinear };
|
||||
|
||||
template <typename TurnInfo,
|
||||
typename SideCalc,
|
||||
typename SegmentP,
|
||||
typename SegmentQ,
|
||||
typename RobustPolicy,
|
||||
typename IntersectionInfo,
|
||||
typename OutIt>
|
||||
static inline bool append_collinear_spikes(TurnInfo & tp,
|
||||
SideCalc const& side_calc,
|
||||
SegmentP const& p1, SegmentP const& p2,
|
||||
SegmentQ const& q1, SegmentQ const& q2,
|
||||
IntersectionInfo const& inters,
|
||||
bool is_p_last, bool is_q_last,
|
||||
method_type method, append_version_c version,
|
||||
RobustPolicy const& robust_policy, OutIt out)
|
||||
OutIt out)
|
||||
{
|
||||
// method == touch || touch_interior
|
||||
// both position == middle
|
||||
@@ -421,12 +380,12 @@ struct get_turn_info_linear_areal
|
||||
|| tp.operations[0].operation == operation_intersection ) :
|
||||
tp.operations[0].operation == operation_continue )
|
||||
&& ! is_p_last
|
||||
&& is_spike_p(side_calc, p1, p2, robust_policy);
|
||||
&& inters.is_spike_p();
|
||||
|
||||
// TODO: throw an exception for spike in Areal?
|
||||
/*bool is_q_spike = tp.operations[1].operation == spike_op
|
||||
&& ! is_q_last
|
||||
&& is_spike_q(side_calc, q1, q2, robust_policy);*/
|
||||
&& inters.is_spike_q();*/
|
||||
|
||||
if ( is_p_spike )
|
||||
{
|
||||
@@ -448,35 +407,28 @@ struct get_turn_info_linear_areal
|
||||
|
||||
template <append_version_o Version,
|
||||
typename TurnInfo,
|
||||
typename Result,
|
||||
typename SideCalc,
|
||||
typename SegmentP,
|
||||
typename SegmentQ,
|
||||
typename RobustPolicy,
|
||||
typename IntersectionInfo,
|
||||
typename OutIt>
|
||||
static inline bool append_opposite_spikes(TurnInfo & tp,
|
||||
Result const& result,
|
||||
SideCalc const& side_calc,
|
||||
SegmentP const& p1, SegmentP const& p2,
|
||||
SegmentQ const& q1, SegmentQ const& q2,
|
||||
IntersectionInfo const& inters,
|
||||
bool is_p_last, bool is_q_last,
|
||||
RobustPolicy const& robust_policy, OutIt out)
|
||||
OutIt out)
|
||||
{
|
||||
bool is_p_spike = ( Version == append_touches ?
|
||||
( tp.operations[0].operation == operation_continue
|
||||
|| tp.operations[0].operation == operation_intersection ) :
|
||||
true )
|
||||
&& ! is_p_last
|
||||
&& is_spike_p(side_calc, p1, p2, robust_policy);
|
||||
&& inters.is_spike_p();
|
||||
// TODO: throw an exception for spike in Areal?
|
||||
/*bool is_q_spike = ( Version == append_touches ?
|
||||
( tp.operations[1].operation == operation_continue
|
||||
|| tp.operations[1].operation == operation_intersection ) :
|
||||
true )
|
||||
&& ! is_q_last
|
||||
&& is_spike_q(side_calc, q1, q2, robust_policy);*/
|
||||
&& inters.is_spike_q();*/
|
||||
|
||||
if ( is_p_spike && ( Version == append_touches || result.template get<1>().arrival[0] == 1 ) )
|
||||
if ( is_p_spike && ( Version == append_touches || inters.d_info().arrival[0] == 1 ) )
|
||||
{
|
||||
if ( Version == append_touches )
|
||||
{
|
||||
@@ -489,12 +441,10 @@ struct get_turn_info_linear_areal
|
||||
//tp.operations[0].is_collinear = true;
|
||||
//tp.operations[1].is_collinear = true;
|
||||
|
||||
//tp.method = method_touch_interior; // only because arrival != 0
|
||||
BOOST_ASSERT(result.template get<0>().count > 1);
|
||||
//geometry::convert(result.template get<0>().intersections[1], tp.point);
|
||||
base_turn_handler::assign_point(tp, method_touch_interior, result.template get<0>(), 1);
|
||||
BOOST_ASSERT(inters.i_info().count > 1);
|
||||
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1);
|
||||
|
||||
AssignPolicy::apply(tp, p1.first, q1.first, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, inters.pi(), inters.qi(), inters.i_info(), inters.d_info());
|
||||
}
|
||||
|
||||
tp.operations[0].operation = operation_blocked;
|
||||
|
||||
@@ -44,27 +44,10 @@ struct get_turn_info_linear_linear
|
||||
RobustPolicy const& robust_policy,
|
||||
OutputIterator out)
|
||||
{
|
||||
typedef model::referring_segment<Point1 const> segment_type1;
|
||||
typedef model::referring_segment<Point2 const> segment_type2;
|
||||
segment_type1 p1(pi, pj), p2(pj, pk);
|
||||
segment_type2 q1(qi, qj), q2(qj, qk);
|
||||
intersection_info<Point1, Point2, typename TurnInfo::point_type, RobustPolicy>
|
||||
inters(pi, pj, pk, qi, qj, qk, robust_policy);
|
||||
|
||||
side_calculator<Point1, Point2> side_calc(pi, pj, pk, qi, qj, qk);
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<typename TurnInfo::point_type>::type,
|
||||
Point1,
|
||||
Point2,
|
||||
typename TurnInfo::point_type,
|
||||
RobustPolicy
|
||||
> si;
|
||||
|
||||
typedef typename si::segment_intersection_strategy_type strategy;
|
||||
|
||||
typename strategy::return_type result = strategy::apply(p1, q1, robust_policy);
|
||||
|
||||
char const method = result.template get<1>().how;
|
||||
char const method = inters.d_info().how;
|
||||
|
||||
// Copy, to copy possibly extended fields
|
||||
TurnInfo tp = tp_model;
|
||||
@@ -78,7 +61,7 @@ struct get_turn_info_linear_linear
|
||||
get_turn_info_for_endpoint<AssignPolicy, true, true>
|
||||
::apply(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, robust_policy, method_none, out);
|
||||
tp_model, inters, method_none, out);
|
||||
break;
|
||||
|
||||
case 'd' : // disjoint: never do anything
|
||||
@@ -89,7 +72,7 @@ struct get_turn_info_linear_linear
|
||||
if ( get_turn_info_for_endpoint<AssignPolicy, false, true>
|
||||
::apply(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, robust_policy, method_touch_interior, out) )
|
||||
tp_model, inters, method_touch_interior, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -101,19 +84,19 @@ struct get_turn_info_linear_linear
|
||||
> policy;
|
||||
|
||||
// If Q (1) arrives (1)
|
||||
if (result.template get<1>().arrival[1] == 1)
|
||||
if ( inters.d_info().arrival[1] == 1)
|
||||
{
|
||||
policy::template apply<0>(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(),
|
||||
side_calc);
|
||||
tp, inters.i_info(), inters.d_info(),
|
||||
inters.sides());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Swap p/q
|
||||
side_calculator<Point2, Point1> swapped_side_calc(qi, qj, qk, pi, pj, pk);
|
||||
policy::template apply<1>(qi, qj, qk, pi, pj, pk,
|
||||
tp, result.template get<0>(), result.template get<1>(),
|
||||
swapped_side_calc);
|
||||
tp, inters.i_info(), inters.d_info(),
|
||||
swapped_side_calc);
|
||||
}
|
||||
|
||||
if ( tp.operations[0].operation == operation_blocked )
|
||||
@@ -125,9 +108,11 @@ struct get_turn_info_linear_linear
|
||||
tp.operations[0].is_collinear = true;
|
||||
}
|
||||
|
||||
replace_method_and_operations_tm(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
replace_method_and_operations_tm(tp.method,
|
||||
tp.operations[0].operation,
|
||||
tp.operations[1].operation);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
@@ -135,11 +120,11 @@ struct get_turn_info_linear_linear
|
||||
case 'i' :
|
||||
{
|
||||
crosses<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>());
|
||||
tp, inters.i_info(), inters.d_info());
|
||||
|
||||
replace_operations_i(tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
@@ -149,14 +134,14 @@ struct get_turn_info_linear_linear
|
||||
if ( get_turn_info_for_endpoint<AssignPolicy, false, true>
|
||||
::apply(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, robust_policy, method_touch, out) )
|
||||
tp_model, inters, method_touch, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
touch<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
if ( tp.operations[0].operation == operation_blocked )
|
||||
{
|
||||
@@ -172,14 +157,12 @@ struct get_turn_info_linear_linear
|
||||
tp.operations[1].operation);
|
||||
|
||||
// TODO: move this into the append_xxx and call for each turn?
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
|
||||
if ( ! handle_spikes
|
||||
|| ! append_opposite_spikes<append_touches>(
|
||||
tp, result, side_calc,
|
||||
p1, p2, q1, q2,
|
||||
is_p_last, is_q_last,
|
||||
robust_policy, out) )
|
||||
|| ! append_opposite_spikes<append_touches>(tp, inters,
|
||||
is_p_last, is_q_last,
|
||||
out) )
|
||||
{
|
||||
*out++ = tp;
|
||||
}
|
||||
@@ -191,7 +174,7 @@ struct get_turn_info_linear_linear
|
||||
if ( get_turn_info_for_endpoint<AssignPolicy, true, true>
|
||||
::apply(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, robust_policy, method_equal, out) )
|
||||
tp_model, inters, method_equal, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -200,25 +183,25 @@ struct get_turn_info_linear_linear
|
||||
tp.operations[0].is_collinear = true;
|
||||
tp.operations[1].is_collinear = true;
|
||||
|
||||
if ( ! result.template get<1>().opposite )
|
||||
if ( ! inters.d_info().opposite )
|
||||
{
|
||||
// Both equal
|
||||
// or collinear-and-ending at intersection point
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
replacer_of_method_and_operations_ec replacer(method_touch);
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
// TODO: move this into the append_xxx and call for each turn?
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
|
||||
// conditionally handle spikes
|
||||
if ( ! handle_spikes
|
||||
|| ! append_collinear_spikes(tp, side_calc, p1, p2, q1, q2,
|
||||
|| ! append_collinear_spikes(tp, inters,
|
||||
is_p_last, is_q_last,
|
||||
method_touch, operation_union,
|
||||
robust_policy, out) )
|
||||
out) )
|
||||
{
|
||||
*out++ = tp; // no spikes
|
||||
}
|
||||
@@ -231,8 +214,7 @@ struct get_turn_info_linear_linear
|
||||
<
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, qi,
|
||||
tp, out, result.template get<0>(), result.template get<1>());
|
||||
>::apply(pi, qi, tp, out, inters.i_info(), inters.d_info());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,7 +225,7 @@ struct get_turn_info_linear_linear
|
||||
if ( get_turn_info_for_endpoint<AssignPolicy, true, true>
|
||||
::apply(pi, pj, pk, qi, qj, qk,
|
||||
is_p_first, is_p_last, is_q_first, is_q_last,
|
||||
tp_model, result, robust_policy, method_collinear, out) )
|
||||
tp_model, inters, method_collinear, out) )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
@@ -252,16 +234,16 @@ struct get_turn_info_linear_linear
|
||||
tp.operations[0].is_collinear = true;
|
||||
tp.operations[1].is_collinear = true;
|
||||
|
||||
if (! result.template get<1>().opposite)
|
||||
if ( ! inters.d_info().opposite )
|
||||
{
|
||||
method_type method_replace = method_touch_interior;
|
||||
operation_type spike_op = operation_continue;
|
||||
|
||||
if (result.template get<1>().arrival[0] == 0)
|
||||
if ( inters.d_info().arrival[0] == 0 )
|
||||
{
|
||||
// Collinear, but similar thus handled as equal
|
||||
equal<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
method_replace = method_touch;
|
||||
spike_op = operation_union;
|
||||
@@ -269,7 +251,7 @@ struct get_turn_info_linear_linear
|
||||
else
|
||||
{
|
||||
collinear<TurnInfo>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, result.template get<0>(), result.template get<1>(), side_calc);
|
||||
tp, inters.i_info(), inters.d_info(), inters.sides());
|
||||
|
||||
//method_replace = method_touch_interior;
|
||||
//spike_op = operation_continue;
|
||||
@@ -279,14 +261,14 @@ struct get_turn_info_linear_linear
|
||||
replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation);
|
||||
|
||||
// TODO: move this into the append_xxx and call for each turn?
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
|
||||
// conditionally handle spikes
|
||||
if ( ! handle_spikes
|
||||
|| ! append_collinear_spikes(tp, side_calc, p1, p2, q1, q2,
|
||||
|| ! append_collinear_spikes(tp, inters,
|
||||
is_p_last, is_q_last,
|
||||
method_replace, spike_op,
|
||||
robust_policy, out) )
|
||||
out) )
|
||||
{
|
||||
// no spikes
|
||||
*out++ = tp;
|
||||
@@ -300,11 +282,9 @@ struct get_turn_info_linear_linear
|
||||
// conditionally handle spikes
|
||||
if ( handle_spikes )
|
||||
{
|
||||
append_opposite_spikes<append_collinear_opposite>(
|
||||
tp, result, side_calc,
|
||||
p1, p2, q1, q2,
|
||||
is_p_last, is_q_last,
|
||||
robust_policy, out);
|
||||
append_opposite_spikes<append_collinear_opposite>(tp, inters,
|
||||
is_p_last, is_q_last,
|
||||
out);
|
||||
}
|
||||
|
||||
// TODO: ignore for spikes?
|
||||
@@ -316,7 +296,7 @@ struct get_turn_info_linear_linear
|
||||
TurnInfo,
|
||||
AssignPolicy
|
||||
>::apply(pi, pj, pk, qi, qj, qk,
|
||||
tp, out, result.template get<0>(), result.template get<1>(), side_calc,
|
||||
tp, out, inters.i_info(), inters.d_info(), inters.sides(),
|
||||
replacer, !is_p_last, !is_q_last);
|
||||
}
|
||||
}
|
||||
@@ -327,7 +307,7 @@ struct get_turn_info_linear_linear
|
||||
// degenerate points
|
||||
if (AssignPolicy::include_degenerate)
|
||||
{
|
||||
only_convert::apply(tp, result.template get<0>());
|
||||
only_convert::apply(tp, inters.i_info());
|
||||
|
||||
// if any, only one of those should be true
|
||||
if ( is_p_first
|
||||
@@ -351,7 +331,7 @@ struct get_turn_info_linear_linear
|
||||
tp.operations[1].position = position_back;
|
||||
}
|
||||
|
||||
AssignPolicy::apply(tp, pi, qi, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, pi, qi, inters.i_info(), inters.d_info());
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
@@ -372,28 +352,23 @@ struct get_turn_info_linear_linear
|
||||
}
|
||||
|
||||
template <typename TurnInfo,
|
||||
typename SideCalc,
|
||||
typename SegmentP,
|
||||
typename SegmentQ,
|
||||
typename RobustPolicy,
|
||||
typename IntersectionInfo,
|
||||
typename OutIt>
|
||||
static inline bool append_collinear_spikes(TurnInfo & tp,
|
||||
SideCalc const& side_calc,
|
||||
SegmentP const& p1, SegmentP const& p2,
|
||||
SegmentQ const& q1, SegmentQ const& q2,
|
||||
IntersectionInfo const& inters_info,
|
||||
bool is_p_last, bool is_q_last,
|
||||
method_type method, operation_type spike_op,
|
||||
RobustPolicy const& robust_policy, OutIt out)
|
||||
OutIt out)
|
||||
{
|
||||
// method == touch || touch_interior
|
||||
// both position == middle
|
||||
|
||||
bool is_p_spike = tp.operations[0].operation == spike_op
|
||||
&& ! is_p_last
|
||||
&& is_spike_p(side_calc, p1, p2, robust_policy);
|
||||
&& inters_info.is_spike_p();
|
||||
bool is_q_spike = tp.operations[1].operation == spike_op
|
||||
&& ! is_q_last
|
||||
&& is_spike_q(side_calc, q1, q2, robust_policy);
|
||||
&& inters_info.is_spike_q();
|
||||
|
||||
if ( is_p_spike && is_q_spike )
|
||||
{
|
||||
@@ -439,36 +414,29 @@ struct get_turn_info_linear_linear
|
||||
|
||||
template <append_version Version,
|
||||
typename TurnInfo,
|
||||
typename Result,
|
||||
typename SideCalc,
|
||||
typename SegmentP,
|
||||
typename SegmentQ,
|
||||
typename RobustPolicy,
|
||||
typename IntersectionInfo,
|
||||
typename OutIt>
|
||||
static inline bool append_opposite_spikes(TurnInfo & tp,
|
||||
Result const& result,
|
||||
SideCalc const& side_calc,
|
||||
SegmentP const& p1, SegmentP const& p2,
|
||||
SegmentQ const& q1, SegmentQ const& q2,
|
||||
IntersectionInfo const& inters,
|
||||
bool is_p_last, bool is_q_last,
|
||||
RobustPolicy const& robust_policy, OutIt out)
|
||||
OutIt out)
|
||||
{
|
||||
bool is_p_spike = ( Version == append_touches ?
|
||||
( tp.operations[0].operation == operation_continue
|
||||
|| tp.operations[0].operation == operation_intersection ) :
|
||||
true )
|
||||
&& ! is_p_last
|
||||
&& is_spike_p(side_calc, p1, p2, robust_policy);
|
||||
&& inters.is_spike_p();
|
||||
bool is_q_spike = ( Version == append_touches ?
|
||||
( tp.operations[1].operation == operation_continue
|
||||
|| tp.operations[1].operation == operation_intersection ) :
|
||||
true )
|
||||
&& ! is_q_last
|
||||
&& is_spike_q(side_calc, q1, q2, robust_policy);
|
||||
&& inters.is_spike_q();
|
||||
|
||||
bool res = false;
|
||||
|
||||
if ( is_p_spike && ( Version == append_touches || result.template get<1>().arrival[0] == 1 ) )
|
||||
if ( is_p_spike && ( Version == append_touches || inters.d_info().arrival[0] == 1 ) )
|
||||
{
|
||||
if ( Version == append_touches )
|
||||
{
|
||||
@@ -481,12 +449,13 @@ struct get_turn_info_linear_linear
|
||||
//tp.operations[0].is_collinear = true;
|
||||
//tp.operations[1].is_collinear = true;
|
||||
|
||||
//tp.method = method_touch_interior; // only because arrival != 0
|
||||
BOOST_ASSERT(result.template get<0>().count > 1);
|
||||
//geometry::convert(result.template get<0>().intersections[1], tp.point);
|
||||
base_turn_handler::assign_point(tp, method_touch_interior, result.template get<0>(), 1);
|
||||
BOOST_ASSERT(inters.i_info().count > 1);
|
||||
|
||||
base_turn_handler::assign_point(tp, method_touch_interior,
|
||||
inters.i_info(), 1);
|
||||
|
||||
AssignPolicy::apply(tp, p1.first, q1.first, result.template get<0>(), result.template get<1>());
|
||||
AssignPolicy::apply(tp, inters.pi(), inters.qi(),
|
||||
inters.i_info(), inters.d_info());
|
||||
}
|
||||
|
||||
tp.operations[0].operation = operation_blocked;
|
||||
@@ -499,7 +468,7 @@ struct get_turn_info_linear_linear
|
||||
res = true;
|
||||
}
|
||||
|
||||
if ( is_q_spike && ( Version == append_touches || result.template get<1>().arrival[1] == 1 ) )
|
||||
if ( is_q_spike && ( Version == append_touches || inters.d_info().arrival[1] == 1 ) )
|
||||
{
|
||||
if ( Version == append_touches )
|
||||
{
|
||||
@@ -512,12 +481,12 @@ struct get_turn_info_linear_linear
|
||||
//tp.operations[0].is_collinear = true;
|
||||
//tp.operations[1].is_collinear = true;
|
||||
|
||||
//tp.method = method_touch_interior; // only because arrival != 0
|
||||
BOOST_ASSERT(result.template get<0>().count > 0);
|
||||
//geometry::convert(result.template get<0>().intersections[0], tp.point);
|
||||
base_turn_handler::assign_point(tp, method_touch_interior, result.template get<0>(), 0);
|
||||
BOOST_ASSERT(inters.i_info().count > 0);
|
||||
|
||||
AssignPolicy::apply(tp, p1.first, q1.first, result.template get<0>(), result.template get<1>());
|
||||
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 0);
|
||||
|
||||
AssignPolicy::apply(tp, inters.pi(), inters.qi(),
|
||||
inters.i_info(), inters.d_info());
|
||||
}
|
||||
|
||||
tp.operations[0].operation = operation_intersection;
|
||||
|
||||
Reference in New Issue
Block a user