diff --git a/include/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp b/include/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp new file mode 100644 index 000000000..14bc3af14 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/distance/polygon_to_segment_or_box.hpp @@ -0,0 +1,152 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POLYGON_TO_SEGMENT_OR_BOX_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POLYGON_TO_SEGMENT_OR_BOX_HPP + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace distance +{ + + +template +struct polygon_to_segment_or_box +{ + typedef typename return_type + < + Strategy, + typename point_type::type, + typename point_type::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) + { + typedef typename geometry::ring_type::type e_ring; + typedef typename geometry::interior_type::type i_rings; + typedef typename range_value::type i_ring; + + if ( geometry::intersects(polygon, segment_or_box) ) + { + return 0; + } + + e_ring const& ext_ring = geometry::exterior_ring(polygon); + i_rings const& int_rings = geometry::interior_rings(polygon); + + comparable_strategy cstrategy = + strategy::distance::services::get_comparable + < + Strategy + >::apply(strategy); + + + return_type cd_min = range_to_segment_or_box + < + e_ring, SegmentOrBox, comparable_strategy + >::apply(ext_ring, segment_or_box, cstrategy, false); + + typedef typename boost::range_iterator::type iterator_type; + for (iterator_type it = boost::begin(int_rings); + it != boost::end(int_rings); ++it) + { + return_type cd = range_to_segment_or_box + < + i_ring, SegmentOrBox, comparable_strategy + >::apply(*it, segment_or_box, cstrategy, false); + + if ( cd < cd_min ) + { + cd_min = cd; + } + } + + return strategy::distance::services::comparable_to_regular + < + comparable_strategy, + Strategy, + Polygon, + SegmentOrBox + >::apply(cd_min); + } +}; + + +}} // namespace detail::distance +#endif // DOXYGEN_NO_DETAIL + + + +#ifndef DOXYGEN_NO_DETAIL +namespace dispatch +{ + + +template +struct distance + < + Polygon, Segment, Strategy, polygon_tag, segment_tag, + strategy_tag_distance_point_segment, false + > + : detail::distance::polygon_to_segment_or_box +{}; + + + +template +struct distance + < + Polygon, Box, Strategy, polygon_tag, box_tag, + strategy_tag_distance_point_segment, false + > + : detail::distance::polygon_to_segment_or_box +{}; + + + +} // namespace dispatch +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_POLYGON_TO_SEGMENT_OR_BOX_HPP