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