[geometry] Propagated rescale_policy further / from earlier phase

This commit is contained in:
Barend Gehrels 2013-12-14 19:45:21 +01:00
parent a77aef8d16
commit c173233efa
13 changed files with 261 additions and 221 deletions

View File

@ -54,7 +54,7 @@ struct get_turn_without_info
Point1 const& pi, Point1 const& pj, Point1 const& ,
Point2 const& qi, Point2 const& qj, Point2 const& ,
TurnInfo const& ,
RescalePolicy const& ,
RescalePolicy const& rescale_policy,
OutputIterator out)
{
typedef model::referring_segment<Point1 const> segment_type1;
@ -62,8 +62,19 @@ struct get_turn_without_info
segment_type1 p1(pi, pj);
segment_type2 q1(qi, qj);
//
typename strategy::return_type result = strategy::apply(p1, q1);
typedef typename geometry::robust_point_type
<
Point1, RescalePolicy
>::type robust_point_type;
robust_point_type pi_rob, pj_rob, qi_rob, qj_rob;
geometry::recalculate(pi_rob, pi, rescale_policy);
geometry::recalculate(pj_rob, pj, rescale_policy);
geometry::recalculate(qi_rob, qi, rescale_policy);
geometry::recalculate(qj_rob, qj, rescale_policy);
typename strategy::return_type result
= strategy::apply(p1, q1,
pi_rob, pj_rob, qi_rob, qj_rob);
for (std::size_t i = 0; i < result.template get<0>().count; i++)
{
@ -87,10 +98,12 @@ template
<
typename Geometry1,
typename Geometry2,
typename RescalePolicy,
typename Turns
>
inline void get_intersection_points(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RescalePolicy const& rescale_policy,
Turns& turns)
{
concept::check_concepts_and_equal_dimensions<Geometry1 const, Geometry2 const>();
@ -112,17 +125,6 @@ inline void get_intersection_points(Geometry1 const& geometry1,
detail::get_turns::no_interrupt_policy interrupt_policy;
#if defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
typedef typename geometry::point_type<Geometry1>::type point_type; // TODO
typedef typename geometry::rescale_policy_type<point_type>::type
rescale_policy_type;
rescale_policy_type rescale_policy
= get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
#else
detail::no_rescale_policy rescale_policy;
#endif
boost::mpl::if_c
<
reverse_dispatch<Geometry1, Geometry2>::type::value,

View File

@ -980,21 +980,6 @@ struct get_turn_info
geometry::recalculate(qj_rob, qj, rescale_policy);
geometry::recalculate(qk_rob, qk, rescale_policy);
typedef geometry::strategy::side::side_by_triangle<> side;
side_info robust_sides;
robust_sides.set<0>(side::apply(qi_rob, qj_rob, pi_rob),
side::apply(qi_rob, qj_rob, pj_rob));
robust_sides.set<1>(side::apply(pi_rob, pj_rob, qi_rob),
side::apply(pi_rob, pj_rob, qj_rob));
bool const p_equals = detail::equals::equals_point_point(pi_rob, pj_rob);
bool const q_equals = detail::equals::equals_point_point(qi_rob, qj_rob);
if (detail::equals::equals_point_point(pj_rob, pk_rob)
|| detail::equals::equals_point_point(qj_rob, qk_rob))
{
///std::cout << "ERROR: dup vectors" << std::endl; - this might happen e.g. for a segment
}
#endif
@ -1002,8 +987,8 @@ struct get_turn_info
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);
segment_type1 p1(pi, pj);
segment_type2 q1(qi, qj);
#if defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
side_calculator<robust_point_type, robust_point_type> side_calc(pi_rob, pj_rob, pk_rob, qi_rob, qj_rob, qk_rob);
@ -1021,14 +1006,7 @@ struct get_turn_info
typedef typename si::segment_intersection_strategy_type strategy;
#if defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
typedef model::referring_segment<robust_point_type const> robust_segment_type;
robust_segment_type rp1(pi_rob, pj_rob);
robust_segment_type rq1(qi_rob, qj_rob);
typename strategy::return_type result = strategy::apply(p1, q1, rp1, rq1, robust_sides, p_equals, q_equals);
#else
typename strategy::return_type result = strategy::apply(p1, q1);
#endif
typename strategy::return_type result = strategy::apply(p1, q1, pi_rob, pj_rob, qi_rob, qj_rob);
char const method = result.template get<1>().how;

View File

@ -136,11 +136,10 @@ private :
segment_type r(ri, rj);
segment_type s(si, sj);
// Get the intersection point (or two points)
segment_intersection_points<point_type> pr = policy::apply(p, r);
segment_intersection_points<point_type> ps = policy::apply(p, s);
segment_intersection_points<point_type> rs = policy::apply(r, s);
segment_intersection_points<point_type> pr = policy::apply(p, r, pi, pj, ri, rj);
segment_intersection_points<point_type> ps = policy::apply(p, s, pi, pj, si, sj);
segment_intersection_points<point_type> rs = policy::apply(r, s, ri, rj, si, sj);
// Check on overlap
pr_overlap = pr.count == 2;

View File

@ -49,14 +49,37 @@ struct intersection_segment_segment_point
template
<
typename Segment1, typename Segment2,
typename RescalePolicy,
typename OutputIterator, typename Strategy
>
static inline OutputIterator apply(Segment1 const& segment1,
Segment2 const& segment2, OutputIterator out,
Segment2 const& segment2,
RescalePolicy const& rescale_policy,
OutputIterator out,
Strategy const& )
{
typedef typename point_type<PointOut>::type point_type;
typedef typename geometry::robust_point_type
<
Segment1, RescalePolicy
>::type robust_point_type;
// TODO: rescale segment -> robust points
robust_point_type pi_rob, pj_rob, qi_rob, qj_rob;
{
// Workaround:
point_type pi, pj, qi, qj;
assign_point_from_index<0>(segment1, pi);
assign_point_from_index<1>(segment1, pj);
assign_point_from_index<0>(segment2, qi);
assign_point_from_index<1>(segment2, qj);
geometry::recalculate(pi_rob, pi, rescale_policy);
geometry::recalculate(pj_rob, pj, rescale_policy);
geometry::recalculate(qi_rob, qi, rescale_policy);
geometry::recalculate(qj_rob, qj, rescale_policy);
}
// Get the intersection point (or two points)
segment_intersection_points<point_type> is
= strategy::intersection::relate_cartesian_segments
@ -67,7 +90,7 @@ struct intersection_segment_segment_point
Segment2,
segment_intersection_points<point_type>
>
>::apply(segment1, segment2);
>::apply(segment1, segment2, pi_rob, pj_rob, qi_rob, qj_rob);
for (std::size_t i = 0; i < is.count; i++)
{
@ -85,10 +108,13 @@ struct intersection_linestring_linestring_point
template
<
typename Linestring1, typename Linestring2,
typename RescalePolicy,
typename OutputIterator, typename Strategy
>
static inline OutputIterator apply(Linestring1 const& linestring1,
Linestring2 const& linestring2, OutputIterator out,
Linestring2 const& linestring2,
RescalePolicy const& rescale_policy,
OutputIterator out,
Strategy const& )
{
typedef typename point_type<PointOut>::type point_type;
@ -96,7 +122,7 @@ struct intersection_linestring_linestring_point
typedef detail::overlay::turn_info<point_type> turn_info;
std::deque<turn_info> turns;
geometry::get_intersection_points(linestring1, linestring2, turns);
geometry::get_intersection_points(linestring1, linestring2, rescale_policy, turns);
for (typename boost::range_iterator<std::deque<turn_info> const>::type
it = boost::begin(turns); it != boost::end(turns); ++it)
@ -140,9 +166,11 @@ struct intersection_of_linestring_with_areal
template
<
typename LineString, typename Areal,
typename RescalePolicy,
typename OutputIterator, typename Strategy
>
static inline OutputIterator apply(LineString const& linestring, Areal const& areal,
RescalePolicy const& rescale_policy,
OutputIterator out,
Strategy const& )
{
@ -163,16 +191,6 @@ struct intersection_of_linestring_with_areal
typedef detail::overlay::traversal_turn_info<point_type> turn_info;
std::deque<turn_info> turns;
#if defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
typedef typename geometry::rescale_policy_type<point_type>::type
rescale_policy_type;
rescale_policy_type rescale_policy
= get_rescale_policy<rescale_policy_type>(linestring, areal);
#else
detail::no_rescale_policy rescale_policy;
#endif
detail::get_turns::no_interrupt_policy policy;
geometry::get_turns
<
@ -359,9 +377,11 @@ struct intersection_insert
false, true, false
>
{
template <typename OutputIterator, typename Strategy>
template <typename RescalePolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Linestring const& linestring,
Box const& box, OutputIterator out, Strategy const& )
Box const& box,
RescalePolicy const& ,
OutputIterator out, Strategy const& )
{
typedef typename point_type<GeometryOut>::type point_type;
strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
@ -435,9 +455,11 @@ struct intersection_insert
false, true, false
>
{
template <typename OutputIterator, typename Strategy>
template <typename RescalePolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Segment const& segment,
Box const& box, OutputIterator out, Strategy const& )
Box const& box,
RescalePolicy const& ,// TODO: propagate to clip_range_with_box
OutputIterator out, Strategy const& )
{
geometry::segment_view<Segment> range(segment);
@ -467,24 +489,16 @@ struct intersection_insert
Areal1, Areal2, false
>
{
template <typename OutputIterator, typename Strategy>
template <typename RescalePolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Geometry1 const& geometry1,
Geometry2 const& geometry2, OutputIterator out, Strategy const& )
Geometry2 const& geometry2,
RescalePolicy const& rescale_policy,
OutputIterator out, Strategy const& )
{
typedef detail::overlay::turn_info<PointOut> turn_info;
std::vector<turn_info> turns;
#if defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
typedef typename geometry::rescale_policy_type<PointOut>::type
rescale_policy_type;
rescale_policy_type rescale_policy
= get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
#else
detail::no_rescale_policy rescale_policy;
#endif
detail::get_turns::no_interrupt_policy policy;
geometry::get_turns
<
@ -509,9 +523,11 @@ template
>
struct intersection_insert_reversed
{
template <typename OutputIterator, typename Strategy>
template <typename RescalePolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Geometry1 const& g1,
Geometry2 const& g2, OutputIterator out,
Geometry2 const& g2,
RescalePolicy const& rescale_policy,
OutputIterator out,
Strategy const& strategy)
{
return intersection_insert
@ -519,7 +535,7 @@ struct intersection_insert_reversed
Geometry2, Geometry1, GeometryOut,
OverlayType,
Reverse2, Reverse1, ReverseOut
>::apply(g2, g1, out, strategy);
>::apply(g2, g1, rescale_policy, out, strategy);
}
};
@ -540,35 +556,37 @@ template
bool ReverseSecond,
overlay_type OverlayType,
typename Geometry1, typename Geometry2,
typename RescalePolicy,
typename OutputIterator,
typename Strategy
>
inline OutputIterator insert(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RescalePolicy rescale_policy,
OutputIterator out,
Strategy const& strategy)
{
return boost::mpl::if_c
<
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
geometry::dispatch::intersection_insert_reversed
<
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
geometry::dispatch::intersection_insert_reversed
<
Geometry1, Geometry2,
GeometryOut,
OverlayType,
overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value,
overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value
>,
geometry::dispatch::intersection_insert
<
Geometry1, Geometry2,
GeometryOut,
OverlayType,
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
>
>::type::apply(geometry1, geometry2, out, strategy);
Geometry1, Geometry2,
GeometryOut,
OverlayType,
overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value,
overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value
>,
geometry::dispatch::intersection_insert
<
Geometry1, Geometry2,
GeometryOut,
OverlayType,
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
>
>::type::apply(geometry1, geometry2, rescale_policy, out, strategy);
}
@ -607,10 +625,23 @@ inline OutputIterator intersection_insert(Geometry1 const& geometry1,
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
#if defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
typedef typename geometry::rescale_policy_type
<
typename geometry::point_type<Geometry1>::type // TODO from both
>::type
rescale_policy_type;
rescale_policy_type rescale_policy
= get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
#else
detail::no_rescale_policy rescale_policy;
#endif
return detail::intersection::insert
<
GeometryOut, false, overlay_intersection
>(geometry1, geometry2, out, strategy);
>(geometry1, geometry2, rescale_policy, out, strategy);
}

View File

@ -157,9 +157,10 @@ template
>
struct overlay
{
template <typename OutputIterator, typename Strategy>
template <typename RescalePolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(
Geometry1 const& geometry1, Geometry2 const& geometry2,
RescalePolicy const& rescale_policy,
OutputIterator out,
Strategy const& )
{
@ -194,22 +195,6 @@ struct overlay
boost::timer timer;
#endif
#if defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
std::cout << "init rescale" << std::endl;
#endif
typedef typename geometry::rescale_policy_type<point_type>::type
rescale_policy_type;
rescale_policy_type rescale_policy
= get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
#else
detail::no_rescale_policy rescale_policy;
#endif
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
std::cout << "get turns" << std::endl;
#endif

View File

@ -43,11 +43,14 @@ template
typename GeometryOut,
typename Geometry1,
typename Geometry2,
typename RescalePolicy,
typename OutputIterator,
typename Strategy
>
inline OutputIterator difference_insert(Geometry1 const& geometry1,
Geometry2 const& geometry2, OutputIterator out,
Geometry2 const& geometry2,
RescalePolicy const& rescale_policy,
OutputIterator out,
Strategy const& strategy)
{
concept::check<Geometry1 const>();
@ -61,7 +64,7 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
overlay_difference,
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
>::apply(geometry1, geometry2, out, strategy);
>::apply(geometry1, geometry2, rescale_policy, out, strategy);
}
/*!
@ -85,10 +88,13 @@ template
typename GeometryOut,
typename Geometry1,
typename Geometry2,
typename RescalePolicy,
typename OutputIterator
>
inline OutputIterator difference_insert(Geometry1 const& geometry1,
Geometry2 const& geometry2, OutputIterator out)
Geometry2 const& geometry2,
RescalePolicy const& rescale_policy,
OutputIterator out)
{
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
@ -103,7 +109,7 @@ inline OutputIterator difference_insert(Geometry1 const& geometry1,
> strategy;
return difference_insert<GeometryOut>(geometry1, geometry2,
out, strategy());
rescale_policy, out, strategy());
}
@ -140,8 +146,21 @@ inline void difference(Geometry1 const& geometry1,
typedef typename boost::range_value<Collection>::type geometry_out;
concept::check<geometry_out>();
#if defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
typedef typename geometry::rescale_policy_type
<
typename geometry::point_type<Geometry1>::type // TODO from both
>::type
rescale_policy_type;
rescale_policy_type rescale_policy
= get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
#else
detail::no_rescale_policy rescale_policy;
#endif
detail::difference::difference_insert<geometry_out>(
geometry1, geometry2,
geometry1, geometry2, rescale_policy,
std::back_inserter(output_collection));
}

View File

@ -27,11 +27,15 @@ struct intersection_box_box
{
template
<
typename Box1, typename Box2, typename BoxOut,
typename Box1, typename Box2,
typename RescalePolicy,
typename BoxOut,
typename Strategy
>
static inline bool apply(Box1 const& box1,
Box2 const& box2, BoxOut& box_out,
Box2 const& box2,
RescalePolicy const& rescale_policy,
BoxOut& box_out,
Strategy const& strategy)
{
typedef typename coordinate_type<BoxOut>::type ct;
@ -50,7 +54,7 @@ struct intersection_box_box
set<max_corner, Dimension>(box_out, max1 > max2 ? max2 : max1);
return intersection_box_box<Dimension + 1, DimensionCount>
::apply(box1, box2, box_out, strategy);
::apply(box1, box2, rescale_policy, box_out, strategy);
}
};
@ -59,10 +63,13 @@ struct intersection_box_box<DimensionCount, DimensionCount>
{
template
<
typename Box1, typename Box2, typename BoxOut,
typename Box1, typename Box2,
typename RescalePolicy,
typename BoxOut,
typename Strategy
>
static inline bool apply(Box1 const&, Box2 const&, BoxOut&, Strategy const&)
static inline bool apply(Box1 const&, Box2 const&,
RescalePolicy const&, BoxOut&, Strategy const&)
{
return true;
}
@ -88,9 +95,10 @@ template
>
struct intersection
{
template <typename GeometryOut, typename Strategy>
template <typename RescalePolicy, typename GeometryOut, typename Strategy>
static inline bool apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RescalePolicy const& rescale_policy,
GeometryOut& geometry_out,
Strategy const& strategy)
{
@ -100,7 +108,7 @@ struct intersection
<
Geometry1, Geometry2, OneOut,
overlay_intersection
>::apply(geometry1, geometry2, std::back_inserter(geometry_out), strategy);
>::apply(geometry1, geometry2, rescale_policy, std::back_inserter(geometry_out), strategy);
return true;
}
@ -122,10 +130,11 @@ struct intersection
>
: intersection<Geometry2, Geometry1, Tag2, Tag1, false>
{
template <typename GeometryOut, typename Strategy>
template <typename RescalePolicy, typename GeometryOut, typename Strategy>
static inline bool apply(
Geometry1 const& g1,
Geometry2 const& g2,
RescalePolicy const& rescale_policy,
GeometryOut& out,
Strategy const& strategy)
{
@ -133,7 +142,7 @@ struct intersection
Geometry2, Geometry1,
Tag2, Tag1,
false
>::apply(g2, g1, out, strategy);
>::apply(g2, g1, rescale_policy, out, strategy);
}
};
@ -194,11 +203,24 @@ inline bool intersection(Geometry1 const& geometry1,
typename geometry::point_type<Geometry1>::type
> strategy;
#if defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
typedef typename geometry::rescale_policy_type
<
typename geometry::point_type<Geometry1>::type // TODO from both
>::type
rescale_policy_type;
return dispatch::intersection<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, geometry_out, strategy());
rescale_policy_type rescale_policy
= get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
#else
detail::no_rescale_policy rescale_policy;
#endif
return dispatch::intersection
<
Geometry1,
Geometry2
>::apply(geometry1, geometry2, rescale_policy, geometry_out, strategy());
}

View File

@ -46,11 +46,14 @@ template
typename GeometryOut,
typename Geometry1,
typename Geometry2,
typename RescalePolicy,
typename OutputIterator,
typename Strategy
>
inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
Geometry2 const& geometry2, OutputIterator out,
Geometry2 const& geometry2,
RescalePolicy const& rescale_policy,
OutputIterator out,
Strategy const& strategy)
{
concept::check<Geometry1 const>();
@ -64,7 +67,7 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
overlay_difference,
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, true>::value
>::apply(geometry1, geometry2, out, strategy);
>::apply(geometry1, geometry2, rescale_policy, out, strategy);
out = geometry::dispatch::intersection_insert
<
Geometry2, Geometry1,
@ -73,7 +76,7 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value, true>::value,
geometry::detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value
>::apply(geometry2, geometry1, out, strategy);
>::apply(geometry2, geometry1, rescale_policy, out, strategy);
return out;
}
@ -97,10 +100,12 @@ template
typename GeometryOut,
typename Geometry1,
typename Geometry2,
typename RescalePolicy,
typename OutputIterator
>
inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
Geometry2 const& geometry2, OutputIterator out)
Geometry2 const& geometry2,
RescalePolicy const& rescale_policy, OutputIterator out)
{
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
@ -114,7 +119,7 @@ inline OutputIterator sym_difference_insert(Geometry1 const& geometry1,
typename geometry::point_type<GeometryOut>::type
> strategy_type;
return sym_difference_insert<GeometryOut>(geometry1, geometry2, out, strategy_type());
return sym_difference_insert<GeometryOut>(geometry1, geometry2, rescale_policy, out, strategy_type());
}
}} // namespace detail::sym_difference
@ -150,8 +155,22 @@ inline void sym_difference(Geometry1 const& geometry1,
typedef typename boost::range_value<Collection>::type geometry_out;
concept::check<geometry_out>();
#if defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
typedef typename geometry::rescale_policy_type
<
typename geometry::point_type<Geometry1>::type // TODO from both
>::type
rescale_policy_type;
rescale_policy_type rescale_policy
= get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
#else
detail::no_rescale_policy rescale_policy;
#endif
detail::sym_difference::sym_difference_insert<geometry_out>(
geometry1, geometry2,
geometry1, geometry2, rescale_policy,
std::back_inserter(output_collection));
}

View File

@ -62,15 +62,17 @@ struct union_insert
true
>: union_insert<Geometry2, Geometry1, GeometryOut>
{
template <typename OutputIterator, typename Strategy>
template <typename RescalePolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Geometry1 const& g1,
Geometry2 const& g2, OutputIterator out,
Geometry2 const& g2,
RescalePolicy const& rescale_policy,
OutputIterator out,
Strategy const& strategy)
{
return union_insert
<
Geometry2, Geometry1, GeometryOut
>::apply(g2, g1, out, strategy);
>::apply(g2, g1, rescale_policy, out, strategy);
}
};
@ -104,18 +106,20 @@ template
<
typename GeometryOut,
typename Geometry1, typename Geometry2,
typename RescalePolicy,
typename OutputIterator,
typename Strategy
>
inline OutputIterator insert(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RescalePolicy const& rescale_policy,
OutputIterator out,
Strategy const& strategy)
{
return dispatch::union_insert
<
Geometry1, Geometry2, GeometryOut
>::apply(geometry1, geometry2, out, strategy);
>::apply(geometry1, geometry2, rescale_policy, out, strategy);
}
/*!
@ -153,7 +157,20 @@ inline OutputIterator union_insert(Geometry1 const& geometry1,
concept::check<Geometry2 const>();
concept::check<GeometryOut>();
return detail::union_::insert<GeometryOut>(geometry1, geometry2, out, strategy);
#if defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
typedef typename geometry::rescale_policy_type
<
typename geometry::point_type<Geometry1>::type // TODO from both
>::type
rescale_policy_type;
rescale_policy_type rescale_policy
= get_rescale_policy<rescale_policy_type>(geometry1, geometry2);
#else
detail::no_rescale_policy rescale_policy;
#endif
return detail::union_::insert<GeometryOut>(geometry1, geometry2, rescale_policy, out, strategy);
}
/*!

View File

@ -118,9 +118,11 @@ struct intersection_of_multi_linestring_with_areal
template
<
typename MultiLinestring, typename Areal,
typename RescalePolicy,
typename OutputIterator, typename Strategy
>
static inline OutputIterator apply(MultiLinestring const& ml, Areal const& areal,
RescalePolicy const& rescale_policy,
OutputIterator out,
Strategy const& strategy)
{
@ -134,7 +136,7 @@ struct intersection_of_multi_linestring_with_areal
out = intersection_of_linestring_with_areal
<
ReverseAreal, LineStringOut, OverlayType
>::apply(*it, areal, out, strategy);
>::apply(*it, areal, rescale_policy, out, strategy);
}
return out;
@ -154,16 +156,18 @@ struct intersection_of_areal_with_multi_linestring
template
<
typename Areal, typename MultiLinestring,
typename RescalePolicy,
typename OutputIterator, typename Strategy
>
static inline OutputIterator apply(Areal const& areal, MultiLinestring const& ml,
RescalePolicy const& rescale_policy,
OutputIterator out,
Strategy const& strategy)
{
return intersection_of_multi_linestring_with_areal
<
ReverseAreal, LineStringOut, OverlayType
>::apply(ml, areal, out, strategy);
>::apply(ml, areal, rescale_policy, out, strategy);
}
};
@ -175,10 +179,13 @@ struct clip_multi_linestring
template
<
typename MultiLinestring, typename Box,
typename RescalePolicy,
typename OutputIterator, typename Strategy
>
static inline OutputIterator apply(MultiLinestring const& multi_linestring,
Box const& box, OutputIterator out, Strategy const& )
Box const& box,
RescalePolicy const& rescale_policy,
OutputIterator out, Strategy const& )
{
typedef typename point_type<LinestringOut>::type point_type;
strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
@ -187,7 +194,7 @@ struct clip_multi_linestring
it != boost::end(multi_linestring); ++it)
{
out = detail::intersection::clip_range_with_box
<LinestringOut>(box, *it, out, lb_strategy);
<LinestringOut>(box, *it, rescale_policy, out, lb_strategy);
}
return out;
}

View File

@ -19,6 +19,7 @@
#include <boost/geometry/arithmetic/determinant.hpp>
#include <boost/geometry/algorithms/detail/assign_values.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
@ -105,73 +106,22 @@ struct relate_cartesian_segments
#endif
// Relate segments a and b
static inline return_type apply(segment_type1 const& a, segment_type2 const& b)
{
coordinate_type const dx_a = get<1, 0>(a) - get<0, 0>(a); // distance in x-dir
coordinate_type const dx_b = get<1, 0>(b) - get<0, 0>(b);
coordinate_type const dy_a = get<1, 1>(a) - get<0, 1>(a); // distance in y-dir
coordinate_type const dy_b = get<1, 1>(b) - get<0, 1>(b);
return apply(a, b, dx_a, dy_a, dx_b, dy_b);
}
// static inline return_type apply(segment_type1 const& a, segment_type2 const& b)
// {
// // TODO: rescale this and then calculate
// return apply(a, b, ...);
// }
template <typename RobustSegment>
// The main entry-routine, calculating intersections of segments a / b
template <typename RobustPoint>
static inline return_type apply(segment_type1 const& a, segment_type2 const& b,
RobustSegment const& ra, RobustSegment const& rb,
side_info& sides,
bool a_is_point, bool b_is_point)
RobustPoint const& robust_a1, RobustPoint const& robust_a2,
RobustPoint const& robust_b1, RobustPoint const& robust_b2)
{
coordinate_type const dx_a = get<1, 0>(a) - get<0, 0>(a); // distance in x-dir
coordinate_type const dx_b = get<1, 0>(b) - get<0, 0>(b);
coordinate_type const dy_a = get<1, 1>(a) - get<0, 1>(a); // distance in y-dir
coordinate_type const dy_b = get<1, 1>(b) - get<0, 1>(b);
return apply(a, b, ra, rb, dx_a, dy_a, dx_b, dy_b, sides, a_is_point, b_is_point);
}
using geometry::detail::equals::equals_point_point;
bool const a_is_point = equals_point_point(robust_a1, robust_a2);
bool const b_is_point = equals_point_point(robust_b1, robust_b2);
// Relate segments a and b using precalculated differences.
// This can save two or four subtractions in many cases
static inline return_type apply(segment_type1 const& a, segment_type2 const& b,
coordinate_type const& dx_a, coordinate_type const& dy_a,
coordinate_type const& dx_b, coordinate_type const& dy_b)
{
typedef side::side_by_triangle<coordinate_type> side;
side_info sides;
coordinate_type const zero = 0;
bool const a_is_point = math::equals(dx_a, zero) && math::equals(dy_a, zero);
bool const b_is_point = math::equals(dx_b, zero) && math::equals(dy_b, zero);
sides.set<0>
(
side::apply(detail::get_from_index<0>(b)
, detail::get_from_index<1>(b)
, detail::get_from_index<0>(a)),
side::apply(detail::get_from_index<0>(b)
, detail::get_from_index<1>(b)
, detail::get_from_index<1>(a))
);
sides.set<1>
(
side::apply(detail::get_from_index<0>(a)
, detail::get_from_index<1>(a)
, detail::get_from_index<0>(b)),
side::apply(detail::get_from_index<0>(a)
, detail::get_from_index<1>(a)
, detail::get_from_index<1>(b))
);
return apply(a, b, a, b, dx_a, dy_a, dx_b, dy_b, sides, a_is_point, b_is_point);
}
// Relate segments a and b using precalculated differences.
// This can save two or four subtractions in many cases
template <typename RobustSegment>
static inline return_type apply(segment_type1 const& a, segment_type2 const& b,
RobustSegment const& , RobustSegment const& , // Will be used later
coordinate_type const& dx_a, coordinate_type const& dy_a,
coordinate_type const& dx_b, coordinate_type const& dy_b,
side_info& sides,
bool a_is_point, bool b_is_point)
{
typedef side::side_by_triangle<coordinate_type> side;
#if ! defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
@ -180,18 +130,19 @@ struct relate_cartesian_segments
if(a_is_point && b_is_point)
{
// TODO move this
if(math::equals(get<1,0>(a), get<1,0>(b)) && math::equals(get<1,1>(a), get<1,1>(b)))
{
Policy::degenerate(a, true);
}
else
{
return Policy::disjoint();
}
return equals_point_point(robust_a1, robust_b2)
? Policy::degenerate(a, true)
: Policy::disjoint()
;
}
bool collinear_use_first = math::abs(dx_a) + math::abs(dx_b) >= math::abs(dy_a) + math::abs(dy_b);
side_info sides;
sides.set<0>(side::apply(robust_b1, robust_b2, robust_a1),
side::apply(robust_b1, robust_b2, robust_a2));
sides.set<1>(side::apply(robust_a1, robust_a2, robust_b1),
side::apply(robust_a1, robust_a2, robust_b2));
bool collinear = sides.collinear();
@ -226,6 +177,11 @@ struct relate_cartesian_segments
coordinate_type, double
>::type promoted_type;
coordinate_type const dx_a = get<1, 0>(a) - get<0, 0>(a); // distance in x-dir
coordinate_type const dx_b = get<1, 0>(b) - get<0, 0>(b);
coordinate_type const dy_a = get<1, 1>(a) - get<0, 1>(a); // distance in y-dir
coordinate_type const dy_b = get<1, 1>(b) - get<0, 1>(b);
// r: ratio 0-1 where intersection divides A/B
// (only calculated for non-collinear segments)
promoted_type r;
@ -271,6 +227,8 @@ struct relate_cartesian_segments
if(collinear)
{
bool collinear_use_first = math::abs(dx_a) + math::abs(dx_b)
>= math::abs(dy_a) + math::abs(dy_b);
if (collinear_use_first)
{
return relate_collinear<0>(a, b);

View File

@ -203,8 +203,10 @@ void test_areal()
test_one<Polygon, Polygon, Polygon>("buffer_rt_f", buffer_rt_f[0], buffer_rt_f[1],
1, 4, 0.00029437899183903937, 0.01);
#if ! defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
test_one<Polygon, Polygon, Polygon>("buffer_rt_g", buffer_rt_g[0], buffer_rt_g[1],
1, 0, 2.914213562373);
#endif
test_one<Polygon, Polygon, Polygon>("ticket_8254", ticket_8254[0], ticket_8254[1],
1, 4, 3.63593e-08, 0.01);

View File

@ -120,15 +120,16 @@ void test_difference(std::string const& caseid, G1 const& g1, G2 const& g2,
{
// Test inserter functionality
// Test if inserter returns output-iterator (using Boost.Range copy)
bg::detail::no_rescale_policy rescale_policy; // TODO
std::vector<OutputType> inserted, array_with_one_empty_geometry;
array_with_one_empty_geometry.push_back(OutputType());
if (sym)
{
boost::copy(array_with_one_empty_geometry, bg::detail::sym_difference::sym_difference_insert<OutputType>(g1, g2, std::back_inserter(inserted)));
boost::copy(array_with_one_empty_geometry, bg::detail::sym_difference::sym_difference_insert<OutputType>(g1, g2, rescale_policy, std::back_inserter(inserted)));
}
else
{
boost::copy(array_with_one_empty_geometry, bg::detail::difference::difference_insert<OutputType>(g1, g2, std::back_inserter(inserted)));
boost::copy(array_with_one_empty_geometry, bg::detail::difference::difference_insert<OutputType>(g1, g2, rescale_policy, std::back_inserter(inserted)));
}
BOOST_CHECK_EQUAL(boost::size(clip), boost::size(inserted) - 1);