File indexing completed on 2025-01-18 09:35:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_DISTANCE_MEASURE_HPP
0014 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_DISTANCE_MEASURE_HPP
0015
0016 #include <boost/geometry/core/access.hpp>
0017 #include <boost/geometry/core/coordinate_system.hpp>
0018 #include <boost/geometry/core/coordinate_type.hpp>
0019 #include <boost/geometry/arithmetic/infinite_line_functions.hpp>
0020 #include <boost/geometry/algorithms/detail/make/make.hpp>
0021 #include <boost/geometry/algorithms/not_implemented.hpp>
0022 #include <boost/geometry/util/select_coordinate_type.hpp>
0023
0024 #include <cmath>
0025
0026 namespace boost { namespace geometry
0027 {
0028
0029 #ifndef DOXYGEN_NO_DETAIL
0030 namespace detail
0031 {
0032
0033 template <typename T>
0034 struct distance_measure
0035 {
0036 T measure;
0037
0038 distance_measure()
0039 : measure(T())
0040 {}
0041
0042
0043 bool is_zero() const
0044 {
0045 return ! is_positive() && ! is_negative();
0046 }
0047
0048
0049
0050 bool is_positive() const { return measure > T(0); }
0051
0052
0053
0054 bool is_negative() const { return measure < T(0); }
0055 };
0056
0057 }
0058
0059
0060 namespace detail_dispatch
0061 {
0062
0063
0064
0065
0066 template <typename CalculationType, typename CsTag>
0067 struct get_distance_measure
0068 : not_implemented<CsTag>
0069 {};
0070
0071 template <typename CalculationType>
0072 struct get_distance_measure<CalculationType, spherical_tag>
0073 {
0074
0075 using result_type = detail::distance_measure<CalculationType>;
0076
0077 template <typename SegmentPoint, typename Point>
0078 static result_type apply(SegmentPoint const& , SegmentPoint const& ,
0079 Point const& )
0080 {
0081 result_type const result;
0082 return result;
0083 }
0084 };
0085
0086 template <typename CalculationType>
0087 struct get_distance_measure<CalculationType, geographic_tag>
0088 : get_distance_measure<CalculationType, spherical_tag>
0089 {};
0090
0091 template <typename CalculationType>
0092 struct get_distance_measure<CalculationType, cartesian_tag>
0093 {
0094 using result_type = detail::distance_measure<CalculationType>;
0095
0096 template <typename SegmentPoint, typename Point>
0097 static result_type apply(SegmentPoint const& p1, SegmentPoint const& p2,
0098 Point const& p)
0099 {
0100
0101
0102
0103 auto const line = detail::make::make_infinite_line<CalculationType>(p1, p2);
0104 result_type result;
0105 result.measure = arithmetic::side_value(line, p);
0106 return result;
0107 }
0108 };
0109
0110 }
0111
0112 namespace detail
0113 {
0114
0115
0116
0117
0118
0119 template <typename SegmentPoint, typename Point, typename Strategies>
0120 inline auto get_distance_measure(SegmentPoint const& p1, SegmentPoint const& p2, Point const& p,
0121 Strategies const&)
0122 {
0123 using calc_t = typename select_coordinate_type<SegmentPoint, Point>::type;
0124
0125
0126
0127
0128 auto identical = [](auto const& point1, auto const& point2)
0129 {
0130 return geometry::get<0>(point1) == geometry::get<0>(point2)
0131 && geometry::get<1>(point1) == geometry::get<1>(point2);
0132 };
0133
0134 if (identical(p1, p) || identical(p2, p))
0135 {
0136 detail::distance_measure<calc_t> const result;
0137 return result;
0138 }
0139
0140 return detail_dispatch::get_distance_measure
0141 <
0142 calc_t,
0143 typename Strategies::cs_tag
0144 >::apply(p1, p2, p);
0145 }
0146
0147 }
0148 #endif
0149
0150 }}
0151
0152 #endif