mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-10 23:42:12 +00:00
[distance] polish code; make clear when the result of comparable or regular strategy is used;
This commit is contained in:
@@ -50,24 +50,33 @@ namespace detail { namespace distance
|
||||
|
||||
|
||||
template <typename Multi1, typename Multi2, typename Strategy>
|
||||
struct distance_multi_to_multi_generic
|
||||
class distance_multi_to_multi_generic
|
||||
{
|
||||
private:
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy,
|
||||
typename point_type<Multi1>::type,
|
||||
typename point_type<Multi2>::type
|
||||
>::type return_type;
|
||||
<
|
||||
comparable_strategy,
|
||||
typename point_type<Multi1>::type,
|
||||
typename point_type<Multi2>::type
|
||||
>::type comparable_return_type;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy,
|
||||
typename point_type<Multi1>::type,
|
||||
typename point_type<Multi2>::type
|
||||
>::type return_type;
|
||||
|
||||
static inline return_type apply(Multi1 const& multi1,
|
||||
Multi2 const& multi2, Strategy const& strategy)
|
||||
{
|
||||
return_type min_cdist = return_type();
|
||||
comparable_return_type min_cdist = comparable_return_type();
|
||||
bool first = true;
|
||||
|
||||
comparable_strategy cstrategy =
|
||||
@@ -80,7 +89,7 @@ struct distance_multi_to_multi_generic
|
||||
it != boost::end(multi1);
|
||||
++it, first = false)
|
||||
{
|
||||
return_type cdist =
|
||||
comparable_return_type cdist =
|
||||
dispatch::splitted_dispatch::distance_single_to_multi
|
||||
<
|
||||
typename range_value<Multi1>::type,
|
||||
|
||||
@@ -56,14 +56,11 @@ namespace detail { namespace distance
|
||||
{
|
||||
|
||||
|
||||
// To avoid spurious namespaces here:
|
||||
using strategy::distance::services::return_type;
|
||||
|
||||
|
||||
template <typename P1, typename P2, typename Strategy>
|
||||
struct point_to_point
|
||||
{
|
||||
static inline typename return_type<Strategy, P1, P2>::type
|
||||
static inline
|
||||
typename strategy::distance::services::return_type<Strategy, P1, P2>::type
|
||||
apply(P1 const& p1, P2 const& p2, Strategy const& strategy)
|
||||
{
|
||||
boost::ignore_unused_variable_warning(strategy);
|
||||
@@ -79,18 +76,25 @@ template
|
||||
closure_selector Closure,
|
||||
typename Strategy
|
||||
>
|
||||
struct point_to_range
|
||||
class point_to_range
|
||||
{
|
||||
typedef typename return_type
|
||||
<
|
||||
Strategy, Point, typename point_type<Range>::type
|
||||
>::type return_type;
|
||||
|
||||
private:
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
comparable_strategy, Point, typename point_type<Range>::type
|
||||
>::type comparable_return_type;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy, Point, typename point_type<Range>::type
|
||||
>::type return_type;
|
||||
|
||||
static inline return_type apply(Point const& point, Range const& range,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
@@ -100,7 +104,7 @@ struct point_to_range
|
||||
Strategy
|
||||
>::apply(strategy);
|
||||
|
||||
return_type const zero = return_type(0);
|
||||
comparable_return_type const zero = comparable_return_type(0);
|
||||
|
||||
if (boost::size(range) == 0)
|
||||
{
|
||||
@@ -126,26 +130,29 @@ struct point_to_range
|
||||
}
|
||||
|
||||
// start with first segment distance
|
||||
return_type d = c_strategy.apply(point, *prev, *it);
|
||||
comparable_return_type cd = c_strategy.apply(point, *prev, *it);
|
||||
|
||||
// check if other segments are closer
|
||||
for (++prev, ++it; it != boost::end(view); ++prev, ++it)
|
||||
{
|
||||
return_type const ds = c_strategy.apply(point, *prev, *it);
|
||||
if (geometry::math::equals(ds, zero))
|
||||
comparable_return_type cds = c_strategy.apply(point, *prev, *it);
|
||||
if (geometry::math::equals(cds, zero))
|
||||
{
|
||||
return ds;
|
||||
return strategy::distance::services::comparable_to_regular
|
||||
<
|
||||
comparable_strategy, Strategy, Point, Range
|
||||
>::apply(zero);
|
||||
}
|
||||
else if (ds < d)
|
||||
else if (cds < cd)
|
||||
{
|
||||
d = ds;
|
||||
cd = cds;
|
||||
}
|
||||
}
|
||||
|
||||
return strategy::distance::services::comparable_to_regular
|
||||
<
|
||||
comparable_strategy, Strategy, Point, Range
|
||||
>::apply(d);
|
||||
>::apply(cd);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -161,7 +168,7 @@ struct point_to_ring
|
||||
{
|
||||
typedef std::pair
|
||||
<
|
||||
typename return_type
|
||||
typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy, Point, typename point_type<Ring>::type
|
||||
>::type,
|
||||
@@ -195,19 +202,31 @@ template
|
||||
closure_selector Closure,
|
||||
typename Strategy
|
||||
>
|
||||
struct point_to_polygon
|
||||
class point_to_polygon
|
||||
{
|
||||
typedef typename return_type
|
||||
<
|
||||
Strategy, Point, typename point_type<Polygon>::type
|
||||
>::type return_type;
|
||||
typedef std::pair<return_type, bool> distance_containment;
|
||||
|
||||
private:
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
comparable_strategy, Point, typename point_type<Polygon>::type
|
||||
>::type comparable_return_type;
|
||||
|
||||
typedef std::pair
|
||||
<
|
||||
comparable_return_type, bool
|
||||
> comparable_distance_containment;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy, Point, typename point_type<Polygon>::type
|
||||
>::type return_type;
|
||||
typedef std::pair<return_type, bool> distance_containment;
|
||||
|
||||
static inline distance_containment apply(Point const& point,
|
||||
Polygon const& polygon,
|
||||
Strategy const& strategy)
|
||||
@@ -227,9 +246,8 @@ struct point_to_polygon
|
||||
comparable_strategy
|
||||
> per_ring;
|
||||
|
||||
distance_containment dc = per_ring::apply(point,
|
||||
exterior_ring(polygon),
|
||||
c_strategy);
|
||||
comparable_distance_containment dc =
|
||||
per_ring::apply(point, exterior_ring(polygon), c_strategy);
|
||||
|
||||
typename interior_return_type<Polygon const>::type rings
|
||||
= interior_rings(polygon);
|
||||
@@ -239,7 +257,8 @@ struct point_to_polygon
|
||||
>::type it = boost::begin(rings);
|
||||
it != boost::end(rings); ++it)
|
||||
{
|
||||
distance_containment dcr = per_ring::apply(point, *it, c_strategy);
|
||||
comparable_distance_containment dcr =
|
||||
per_ring::apply(point, *it, c_strategy);
|
||||
if (dcr.first < dc.first)
|
||||
{
|
||||
dc.first = dcr.first;
|
||||
@@ -305,11 +324,14 @@ struct distance
|
||||
false
|
||||
>
|
||||
{
|
||||
typedef typename return_type<Strategy, Point, typename point_type<Ring>::type>::type return_type;
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy, Point, typename point_type<Ring>::type
|
||||
>::type return_type;
|
||||
|
||||
static inline return_type apply(Point const& point,
|
||||
Ring const& ring,
|
||||
Strategy const& strategy)
|
||||
Ring const& ring,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
std::pair<return_type, bool>
|
||||
dc = detail::distance::point_to_ring
|
||||
@@ -332,11 +354,14 @@ struct distance
|
||||
strategy_tag_distance_point_segment, false
|
||||
>
|
||||
{
|
||||
typedef typename return_type<Strategy, Point, typename point_type<Polygon>::type>::type return_type;
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy, Point, typename point_type<Polygon>::type
|
||||
>::type return_type;
|
||||
|
||||
static inline return_type apply(Point const& point,
|
||||
Polygon const& polygon,
|
||||
Strategy const& strategy)
|
||||
Polygon const& polygon,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
std::pair<return_type, bool>
|
||||
dc = detail::distance::point_to_polygon
|
||||
|
||||
@@ -42,20 +42,29 @@ namespace detail { namespace distance
|
||||
|
||||
|
||||
template <typename Polygon, typename SegmentOrBox, typename Strategy>
|
||||
struct polygon_to_segment_or_box
|
||||
class polygon_to_segment_or_box
|
||||
{
|
||||
typedef typename return_type
|
||||
private:
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
comparable_strategy,
|
||||
typename point_type<Polygon>::type,
|
||||
typename point_type<SegmentOrBox>::type
|
||||
>::type comparable_return_type;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy,
|
||||
typename point_type<Polygon>::type,
|
||||
typename point_type<SegmentOrBox>::type
|
||||
>::type return_type;
|
||||
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
static inline return_type apply(Polygon const& polygon,
|
||||
SegmentOrBox const& segment_or_box,
|
||||
Strategy const& strategy)
|
||||
@@ -79,7 +88,7 @@ struct polygon_to_segment_or_box
|
||||
>::apply(strategy);
|
||||
|
||||
|
||||
return_type cd_min = range_to_segment_or_box
|
||||
comparable_return_type cd_min = range_to_segment_or_box
|
||||
<
|
||||
e_ring, SegmentOrBox, comparable_strategy
|
||||
>::apply(ext_ring, segment_or_box, cstrategy, false);
|
||||
@@ -88,7 +97,7 @@ struct polygon_to_segment_or_box
|
||||
for (iterator_type it = boost::begin(int_rings);
|
||||
it != boost::end(int_rings); ++it)
|
||||
{
|
||||
return_type cd = range_to_segment_or_box
|
||||
comparable_return_type cd = range_to_segment_or_box
|
||||
<
|
||||
i_ring, SegmentOrBox, comparable_strategy
|
||||
>::apply(*it, segment_or_box, cstrategy, false);
|
||||
|
||||
@@ -57,18 +57,16 @@ private:
|
||||
typedef typename point_type<SegmentOrBox>::type segment_or_box_point;
|
||||
typedef typename point_type<Range>::type range_point;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy, range_point, segment_or_box_point
|
||||
>::type return_type;
|
||||
|
||||
private:
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
comparable_strategy, range_point, segment_or_box_point
|
||||
>::type comparable_return_type;
|
||||
|
||||
typedef typename strategy::distance::services::tag
|
||||
<
|
||||
comparable_strategy
|
||||
@@ -79,7 +77,7 @@ private:
|
||||
segment_or_box_point, Range, comparable_strategy,
|
||||
point_tag, typename tag<Range>::type,
|
||||
comparable_strategy_tag, false
|
||||
> point_to_range;
|
||||
> comparable_point_to_range;
|
||||
|
||||
// compute distance of a point to a segment or a box
|
||||
template
|
||||
@@ -89,7 +87,7 @@ private:
|
||||
typename ComparableStrategy,
|
||||
typename Tag
|
||||
>
|
||||
struct distance_point_to_segment_or_box
|
||||
struct comparable_distance_point_to_segment_or_box
|
||||
{};
|
||||
|
||||
template
|
||||
@@ -98,14 +96,15 @@ private:
|
||||
typename SegmentPoints,
|
||||
typename ComparableStrategy
|
||||
>
|
||||
struct distance_point_to_segment_or_box
|
||||
struct comparable_distance_point_to_segment_or_box
|
||||
<
|
||||
Point, SegmentPoints, ComparableStrategy, segment_tag
|
||||
>
|
||||
{
|
||||
static inline return_type apply(Point const& point,
|
||||
SegmentPoints const& segment_points,
|
||||
ComparableStrategy const& strategy)
|
||||
static inline
|
||||
comparable_return_type apply(Point const& point,
|
||||
SegmentPoints const& segment_points,
|
||||
ComparableStrategy const& strategy)
|
||||
{
|
||||
return strategy.apply(point, segment_points[0], segment_points[1]);
|
||||
}
|
||||
@@ -117,21 +116,22 @@ private:
|
||||
typename BoxPoints,
|
||||
typename ComparableStrategy
|
||||
>
|
||||
struct distance_point_to_segment_or_box
|
||||
struct comparable_distance_point_to_segment_or_box
|
||||
<
|
||||
Point, BoxPoints, ComparableStrategy, box_tag
|
||||
>
|
||||
{
|
||||
static inline return_type apply(Point const& point,
|
||||
BoxPoints const& box_points,
|
||||
ComparableStrategy const& strategy)
|
||||
static inline
|
||||
comparable_return_type apply(Point const& point,
|
||||
BoxPoints const& box_points,
|
||||
ComparableStrategy const& strategy)
|
||||
{
|
||||
return_type cd_min =
|
||||
comparable_return_type cd_min =
|
||||
strategy.apply(point, box_points[0], box_points[3]);
|
||||
|
||||
for (unsigned int i = 0; i < 2; ++i)
|
||||
{
|
||||
return_type cd =
|
||||
comparable_return_type cd =
|
||||
strategy.apply(point, box_points[i], box_points[i+1]);
|
||||
|
||||
if ( cd < cd_min )
|
||||
@@ -177,6 +177,11 @@ private:
|
||||
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy, range_point, segment_or_box_point
|
||||
>::type return_type;
|
||||
|
||||
static inline return_type
|
||||
apply(Range const& range, SegmentOrBox const& segment_or_box,
|
||||
Strategy const& strategy, bool check_intersection = true)
|
||||
@@ -208,11 +213,13 @@ public:
|
||||
// to the range
|
||||
typename std::vector<segment_or_box_point>::const_iterator it
|
||||
= segment_or_box_points.begin();
|
||||
return_type cd_min = point_to_range::apply(*it, range, cstrategy);
|
||||
comparable_return_type cd_min =
|
||||
comparable_point_to_range::apply(*it, range, cstrategy);
|
||||
|
||||
for (++it; it != segment_or_box_points.end(); ++it)
|
||||
{
|
||||
return_type cd = point_to_range::apply(*it, range, cstrategy);
|
||||
comparable_return_type cd =
|
||||
comparable_point_to_range::apply(*it, range, cstrategy);
|
||||
if ( cd < cd_min )
|
||||
{
|
||||
cd_min = cd;
|
||||
@@ -224,13 +231,14 @@ public:
|
||||
typedef typename range_iterator<Range const>::type iterator_type;
|
||||
for (iterator_type it = boost::begin(range); it != boost::end(range); ++it)
|
||||
{
|
||||
return_type cd = distance_point_to_segment_or_box
|
||||
<
|
||||
typename point_type<Range>::type,
|
||||
std::vector<segment_or_box_point>,
|
||||
comparable_strategy,
|
||||
typename tag<SegmentOrBox>::type
|
||||
>::apply(*it, segment_or_box_points, cstrategy);
|
||||
comparable_return_type cd =
|
||||
comparable_distance_point_to_segment_or_box
|
||||
<
|
||||
typename point_type<Range>::type,
|
||||
std::vector<segment_or_box_point>,
|
||||
comparable_strategy,
|
||||
typename tag<SegmentOrBox>::type
|
||||
>::apply(*it, segment_or_box_points, cstrategy);
|
||||
|
||||
if ( cd < cd_min )
|
||||
{
|
||||
|
||||
@@ -407,6 +407,10 @@ private:
|
||||
PSStrategy
|
||||
>::type ps_comparable_strategy;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
ps_comparable_strategy, segment_point, box_point
|
||||
>::type comparable_return_type;
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
@@ -468,11 +472,11 @@ public:
|
||||
PSStrategy
|
||||
>::apply(ps_strategy);
|
||||
|
||||
return_type d;
|
||||
comparable_return_type cd;
|
||||
|
||||
if ( geometry::less<segment_point>()(p[0], p[1]) )
|
||||
{
|
||||
d = segment_to_box_2D
|
||||
cd = segment_to_box_2D
|
||||
<
|
||||
return_type,
|
||||
segment_point,
|
||||
@@ -486,7 +490,7 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
d = segment_to_box_2D
|
||||
cd = segment_to_box_2D
|
||||
<
|
||||
return_type,
|
||||
segment_point,
|
||||
@@ -502,7 +506,7 @@ public:
|
||||
return strategy::distance::services::comparable_to_regular
|
||||
<
|
||||
ps_comparable_strategy, PSStrategy, Segment, Box
|
||||
>::apply( d );
|
||||
>::apply( cd );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -37,8 +37,22 @@ namespace detail { namespace distance
|
||||
|
||||
// compute segment-segment distance
|
||||
template<typename Segment1, typename Segment2, typename Strategy>
|
||||
struct segment_to_segment
|
||||
class segment_to_segment
|
||||
{
|
||||
private:
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
comparable_strategy,
|
||||
typename point_type<Segment1>::type,
|
||||
typename point_type<Segment2>::type
|
||||
>::type comparable_return_type;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy,
|
||||
@@ -46,11 +60,6 @@ struct segment_to_segment
|
||||
typename point_type<Segment2>::type
|
||||
>::type return_type;
|
||||
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
static inline return_type
|
||||
apply(Segment1 const& segment1, Segment2 const& segment2,
|
||||
Strategy const& strategy)
|
||||
@@ -74,7 +83,7 @@ struct segment_to_segment
|
||||
Strategy
|
||||
>::apply(strategy);
|
||||
|
||||
return_type d[4];
|
||||
comparable_return_type d[4];
|
||||
d[0] = cstrategy.apply(q[0], p[0], p[1]);
|
||||
d[1] = cstrategy.apply(q[1], p[0], p[1]);
|
||||
d[2] = cstrategy.apply(p[0], q[0], q[1]);
|
||||
|
||||
@@ -67,25 +67,34 @@ namespace detail { namespace distance
|
||||
|
||||
|
||||
template<typename Geometry, typename MultiGeometry, typename Strategy>
|
||||
struct distance_single_to_multi_generic
|
||||
class distance_single_to_multi_generic
|
||||
{
|
||||
private:
|
||||
typedef typename strategy::distance::services::comparable_type
|
||||
<
|
||||
Strategy
|
||||
>::type comparable_strategy;
|
||||
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy,
|
||||
typename point_type<Geometry>::type,
|
||||
typename point_type<MultiGeometry>::type
|
||||
>::type return_type;
|
||||
<
|
||||
comparable_strategy,
|
||||
typename point_type<Geometry>::type,
|
||||
typename point_type<MultiGeometry>::type
|
||||
>::type comparable_return_type;
|
||||
|
||||
public:
|
||||
typedef typename strategy::distance::services::return_type
|
||||
<
|
||||
Strategy,
|
||||
typename point_type<Geometry>::type,
|
||||
typename point_type<MultiGeometry>::type
|
||||
>::type return_type;
|
||||
|
||||
static inline return_type apply(Geometry const& geometry,
|
||||
MultiGeometry const& multi,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return_type min_cdist = return_type();
|
||||
comparable_return_type min_cdist = comparable_return_type();
|
||||
bool first = true;
|
||||
|
||||
comparable_strategy cstrategy =
|
||||
@@ -98,7 +107,7 @@ struct distance_single_to_multi_generic
|
||||
it != boost::end(multi);
|
||||
++it, first = false)
|
||||
{
|
||||
return_type cdist = dispatch::distance
|
||||
comparable_return_type cdist = dispatch::distance
|
||||
<
|
||||
Geometry,
|
||||
typename range_value<MultiGeometry>::type,
|
||||
|
||||
Reference in New Issue
Block a user