File indexing completed on 2025-01-18 09:35:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP
0012 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_SEGMENT_HPP
0013
0014 #include <algorithm>
0015 #include <iterator>
0016
0017 #include <boost/core/addressof.hpp>
0018
0019 #include <boost/geometry/algorithms/assign.hpp>
0020 #include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
0021 #include <boost/geometry/algorithms/detail/distance/strategy_utils.hpp>
0022 #include <boost/geometry/algorithms/dispatch/distance.hpp>
0023 #include <boost/geometry/algorithms/intersects.hpp>
0024
0025 #include <boost/geometry/core/point_type.hpp>
0026 #include <boost/geometry/core/tags.hpp>
0027
0028 #include <boost/geometry/strategies/distance.hpp>
0029 #include <boost/geometry/strategies/tags.hpp>
0030
0031 #include <boost/geometry/util/condition.hpp>
0032
0033
0034 namespace boost { namespace geometry
0035 {
0036
0037
0038 #ifndef DOXYGEN_NO_DETAIL
0039 namespace detail { namespace distance
0040 {
0041
0042
0043
0044
0045 template<typename Segment1, typename Segment2, typename Strategies>
0046 class segment_to_segment
0047 {
0048 typedef distance::strategy_t<Segment1, Segment2, Strategies> strategy_type;
0049
0050 public:
0051 typedef distance::return_t<Segment1, Segment2, Strategies> return_type;
0052
0053 static inline return_type apply(Segment1 const& segment1, Segment2 const& segment2,
0054 Strategies const& strategies)
0055 {
0056 if (geometry::intersects(segment1, segment2, strategies))
0057 {
0058 return 0;
0059 }
0060
0061 typename point_type<Segment1>::type p[2];
0062 detail::assign_point_from_index<0>(segment1, p[0]);
0063 detail::assign_point_from_index<1>(segment1, p[1]);
0064
0065 typename point_type<Segment2>::type q[2];
0066 detail::assign_point_from_index<0>(segment2, q[0]);
0067 detail::assign_point_from_index<1>(segment2, q[1]);
0068
0069 strategy_type const strategy = strategies.distance(segment1, segment2);
0070
0071 auto const cstrategy = strategy::distance::services::get_comparable
0072 <
0073 strategy_type
0074 >::apply(strategy);
0075
0076 distance::creturn_t<Segment1, Segment2, Strategies> d[4];
0077 d[0] = cstrategy.apply(q[0], p[0], p[1]);
0078 d[1] = cstrategy.apply(q[1], p[0], p[1]);
0079 d[2] = cstrategy.apply(p[0], q[0], q[1]);
0080 d[3] = cstrategy.apply(p[1], q[0], q[1]);
0081
0082 std::size_t imin = std::distance(boost::addressof(d[0]),
0083 std::min_element(d, d + 4));
0084
0085 if (BOOST_GEOMETRY_CONDITION(is_comparable<strategy_type>::value))
0086 {
0087 return d[imin];
0088 }
0089
0090 switch (imin)
0091 {
0092 case 0:
0093 return strategy.apply(q[0], p[0], p[1]);
0094 case 1:
0095 return strategy.apply(q[1], p[0], p[1]);
0096 case 2:
0097 return strategy.apply(p[0], q[0], q[1]);
0098 default:
0099 return strategy.apply(p[1], q[0], q[1]);
0100 }
0101 }
0102 };
0103
0104
0105
0106
0107 }}
0108 #endif
0109
0110
0111 #ifndef DOXYGEN_NO_DISPATCH
0112 namespace dispatch
0113 {
0114
0115
0116
0117
0118 template <typename Segment1, typename Segment2, typename Strategy>
0119 struct distance
0120 <
0121 Segment1, Segment2, Strategy, segment_tag, segment_tag,
0122 strategy_tag_distance_point_segment, false
0123 >
0124 : detail::distance::segment_to_segment<Segment1, Segment2, Strategy>
0125 {};
0126
0127
0128
0129 }
0130 #endif
0131
0132
0133 }}
0134
0135
0136 #endif