%PDF- %PDF-
| Direktori : /usr/include/boost/geometry/algorithms/detail/distance/ |
| Current File : //usr/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp |
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, 2019, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, 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_SEGMENT_TO_SEGMENT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP
#include <algorithm>
#include <iterator>
#include <boost/core/addressof.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace distance
{
// compute segment-segment distance
template<typename Segment1, typename Segment2, typename Strategy>
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,
typename point_type<Segment1>::type,
typename point_type<Segment2>::type
>::type return_type;
static inline return_type
apply(Segment1 const& segment1, Segment2 const& segment2,
Strategy const& strategy)
{
if (geometry::intersects(segment1, segment2, strategy.get_relate_segment_segment_strategy()))
{
return 0;
}
typename point_type<Segment1>::type p[2];
detail::assign_point_from_index<0>(segment1, p[0]);
detail::assign_point_from_index<1>(segment1, p[1]);
typename point_type<Segment2>::type q[2];
detail::assign_point_from_index<0>(segment2, q[0]);
detail::assign_point_from_index<1>(segment2, q[1]);
comparable_strategy cstrategy =
strategy::distance::services::get_comparable
<
Strategy
>::apply(strategy);
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]);
d[3] = cstrategy.apply(p[1], q[0], q[1]);
std::size_t imin = std::distance(boost::addressof(d[0]),
std::min_element(d, d + 4));
if (BOOST_GEOMETRY_CONDITION(is_comparable<Strategy>::value))
{
return d[imin];
}
switch (imin)
{
case 0:
return strategy.apply(q[0], p[0], p[1]);
case 1:
return strategy.apply(q[1], p[0], p[1]);
case 2:
return strategy.apply(p[0], q[0], q[1]);
default:
return strategy.apply(p[1], q[0], q[1]);
}
}
};
}} // namespace detail::distance
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// segment-segment
template <typename Segment1, typename Segment2, typename Strategy>
struct distance
<
Segment1, Segment2, Strategy, segment_tag, segment_tag,
strategy_tag_distance_point_segment, false
>
: detail::distance::segment_to_segment<Segment1, Segment2, Strategy>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP