mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-11 11:52:11 +00:00
Merge branch 'develop' of github.com:boostorg/geometry into develop
This commit is contained in:
@@ -38,96 +38,115 @@ 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(pi(), 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(qi(), qj(), qk());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Point>
|
||||
inline bool is_spike_of_collinear(Point const& i, Point const& j, Point const& k) const
|
||||
{
|
||||
typedef model::referring_segment<Point const> seg_t;
|
||||
|
||||
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(seg_t(i, j), seg_t(j, k), 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 +354,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 +362,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 +378,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 +399,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 +410,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 +419,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 +450,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 +473,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 +513,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;
|
||||
|
||||
@@ -335,7 +335,6 @@ void test_boxes(std::string const& wkt1, std::string const& wkt2, double expecte
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename P>
|
||||
void test_point_output()
|
||||
{
|
||||
@@ -401,7 +400,6 @@ void test_areal_linear()
|
||||
|
||||
}
|
||||
|
||||
|
||||
template <typename P>
|
||||
void test_all()
|
||||
{
|
||||
@@ -563,6 +561,37 @@ void test_rational()
|
||||
}
|
||||
|
||||
|
||||
template <typename P>
|
||||
void test_boxes_per_d(P const& min1, P const& max1, P const& min2, P const& max2, bool expected_result)
|
||||
{
|
||||
typedef bg::model::box<P> box;
|
||||
|
||||
box box_out;
|
||||
bool detected = bg::intersection(box(min1, max1), box(min2, max2), box_out);
|
||||
|
||||
BOOST_CHECK_EQUAL(detected, expected_result);
|
||||
if ( detected && expected_result )
|
||||
{
|
||||
BOOST_CHECK( bg::equals(box_out, box(min2,max1)) );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CoordinateType>
|
||||
void test_boxes_nd()
|
||||
{
|
||||
typedef bg::model::point<CoordinateType, 1, bg::cs::cartesian> p1;
|
||||
typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> p2;
|
||||
typedef bg::model::point<CoordinateType, 3, bg::cs::cartesian> p3;
|
||||
typedef bg::model::box<p1> b1;
|
||||
typedef bg::model::box<p1> b2;
|
||||
typedef bg::model::box<p1> b3;
|
||||
|
||||
test_boxes_per_d(p1(0), p1(5), p1(3), p1(6), true);
|
||||
test_boxes_per_d(p2(0,0), p2(5,5), p2(3,3), p2(6,6), true);
|
||||
test_boxes_per_d(p3(0,0,0), p3(5,5,5), p3(3,3,3), p3(6,6,6), true);
|
||||
}
|
||||
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
test_all<bg::model::d2::point_xy<double> >();
|
||||
@@ -583,6 +612,8 @@ int test_main(int, char* [])
|
||||
test_rational<bg::model::d2::point_xy<boost::rational<int> > >();
|
||||
#endif
|
||||
|
||||
test_boxes_nd<double>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user