1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2014, Oracle and/or its affiliates.
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7 // Licensed under the Boost Software License version 1.0.
8 // http://www.boost.org/users/license.html
10 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP
11 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP
16 #include <boost/core/addressof.hpp>
18 #include <boost/geometry/core/point_type.hpp>
19 #include <boost/geometry/core/tags.hpp>
21 #include <boost/geometry/util/condition.hpp>
23 #include <boost/geometry/strategies/distance.hpp>
24 #include <boost/geometry/strategies/tags.hpp>
26 #include <boost/geometry/algorithms/assign.hpp>
27 #include <boost/geometry/algorithms/intersects.hpp>
29 #include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
31 #include <boost/geometry/algorithms/dispatch/distance.hpp>
34 namespace boost { namespace geometry
38 #ifndef DOXYGEN_NO_DETAIL
39 namespace detail { namespace distance
44 // compute segment-segment distance
45 template<typename Segment1, typename Segment2, typename Strategy>
46 class segment_to_segment
49 typedef typename strategy::distance::services::comparable_type
52 >::type comparable_strategy;
54 typedef typename strategy::distance::services::return_type
57 typename point_type<Segment1>::type,
58 typename point_type<Segment2>::type
59 >::type comparable_return_type;
62 typedef typename strategy::distance::services::return_type
65 typename point_type<Segment1>::type,
66 typename point_type<Segment2>::type
69 static inline return_type
70 apply(Segment1 const& segment1, Segment2 const& segment2,
71 Strategy const& strategy)
73 if (geometry::intersects(segment1, segment2))
78 typename point_type<Segment1>::type p[2];
79 detail::assign_point_from_index<0>(segment1, p[0]);
80 detail::assign_point_from_index<1>(segment1, p[1]);
82 typename point_type<Segment2>::type q[2];
83 detail::assign_point_from_index<0>(segment2, q[0]);
84 detail::assign_point_from_index<1>(segment2, q[1]);
86 comparable_strategy cstrategy =
87 strategy::distance::services::get_comparable
92 comparable_return_type d[4];
93 d[0] = cstrategy.apply(q[0], p[0], p[1]);
94 d[1] = cstrategy.apply(q[1], p[0], p[1]);
95 d[2] = cstrategy.apply(p[0], q[0], q[1]);
96 d[3] = cstrategy.apply(p[1], q[0], q[1]);
98 std::size_t imin = std::distance(boost::addressof(d[0]),
99 std::min_element(d, d + 4));
101 if (BOOST_GEOMETRY_CONDITION(is_comparable<Strategy>::value))
109 return strategy.apply(q[0], p[0], p[1]);
111 return strategy.apply(q[1], p[0], p[1]);
113 return strategy.apply(p[0], q[0], q[1]);
115 return strategy.apply(p[1], q[0], q[1]);
123 }} // namespace detail::distance
124 #endif // DOXYGEN_NO_DETAIL
127 #ifndef DOXYGEN_NO_DISPATCH
134 template <typename Segment1, typename Segment2, typename Strategy>
137 Segment1, Segment2, Strategy, segment_tag, segment_tag,
138 strategy_tag_distance_point_segment, false
140 : detail::distance::segment_to_segment<Segment1, Segment2, Strategy>
145 } // namespace dispatch
146 #endif // DOXYGEN_NO_DISPATCH
149 }} // namespace boost::geometry
152 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP