File indexing completed on 2025-01-18 09:36:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
0020 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
0021
0022
0023 #include <boost/geometry/core/access.hpp>
0024
0025 #include <boost/geometry/geometries/concepts/point_concept.hpp>
0026
0027 #include <boost/geometry/strategies/distance.hpp>
0028
0029 #include <boost/geometry/util/math.hpp>
0030 #include <boost/geometry/util/calculation_type.hpp>
0031
0032
0033 namespace boost { namespace geometry
0034 {
0035
0036 namespace strategy { namespace distance
0037 {
0038
0039 #ifndef DOXYGEN_NO_DETAIL
0040 namespace detail
0041 {
0042
0043 template <size_t I, typename T>
0044 struct compute_pythagoras
0045 {
0046 template <typename Point1, typename Point2>
0047 static inline T apply(Point1 const& p1, Point2 const& p2)
0048 {
0049 T const c1 = boost::numeric_cast<T>(get<I-1>(p1));
0050 T const c2 = boost::numeric_cast<T>(get<I-1>(p2));
0051 T const d = c1 - c2;
0052 return d * d + compute_pythagoras<I-1, T>::apply(p1, p2);
0053 }
0054 };
0055
0056 template <typename T>
0057 struct compute_pythagoras<0, T>
0058 {
0059 template <typename Point1, typename Point2>
0060 static inline T apply(Point1 const&, Point2 const&)
0061 {
0062 return boost::numeric_cast<T>(0);
0063 }
0064 };
0065
0066 }
0067 #endif
0068
0069
0070 namespace comparable
0071 {
0072
0073
0074
0075
0076
0077
0078
0079
0080 template <typename CalculationType = void>
0081 class pythagoras
0082 {
0083 public :
0084
0085 template <typename Point1, typename Point2>
0086 struct calculation_type
0087 : util::calculation_type::geometric::binary
0088 <
0089 Point1,
0090 Point2,
0091 CalculationType,
0092 double,
0093 double
0094 >
0095 {};
0096
0097 template <typename Point1, typename Point2>
0098 static inline typename calculation_type<Point1, Point2>::type
0099 apply(Point1 const& p1, Point2 const& p2)
0100 {
0101 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point1>) );
0102 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
0103
0104
0105
0106
0107 assert_dimension_equal<Point1, Point2>();
0108
0109 return detail::compute_pythagoras
0110 <
0111 dimension<Point1>::value,
0112 typename calculation_type<Point1, Point2>::type
0113 >::apply(p1, p2);
0114 }
0115 };
0116
0117 }
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 template
0134 <
0135 typename CalculationType = void
0136 >
0137 class pythagoras
0138 {
0139 public :
0140
0141 template <typename P1, typename P2>
0142 struct calculation_type
0143 : util::calculation_type::geometric::binary
0144 <
0145 P1,
0146 P2,
0147 CalculationType,
0148 double,
0149 double
0150 >
0151 {};
0152
0153
0154
0155
0156
0157
0158
0159 template <typename P1, typename P2>
0160 static inline typename calculation_type<P1, P2>::type
0161 apply(P1 const& p1, P2 const& p2)
0162 {
0163
0164 return math::sqrt
0165 (
0166 boost::numeric_cast<typename calculation_type<P1, P2>::type>
0167 (
0168 comparable::pythagoras<CalculationType>::apply(p1, p2)
0169 )
0170 );
0171 }
0172 };
0173
0174
0175 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0176 namespace services
0177 {
0178
0179 template <typename CalculationType>
0180 struct tag<pythagoras<CalculationType> >
0181 {
0182 typedef strategy_tag_distance_point_point type;
0183 };
0184
0185
0186 template <typename CalculationType, typename P1, typename P2>
0187 struct return_type<distance::pythagoras<CalculationType>, P1, P2>
0188 : pythagoras<CalculationType>::template calculation_type<P1, P2>
0189 {};
0190
0191
0192 template <typename CalculationType>
0193 struct comparable_type<pythagoras<CalculationType> >
0194 {
0195 typedef comparable::pythagoras<CalculationType> type;
0196 };
0197
0198
0199 template <typename CalculationType>
0200 struct get_comparable<pythagoras<CalculationType> >
0201 {
0202 typedef comparable::pythagoras<CalculationType> comparable_type;
0203 public :
0204 static inline comparable_type apply(pythagoras<CalculationType> const& )
0205 {
0206 return comparable_type();
0207 }
0208 };
0209
0210
0211 template <typename CalculationType, typename Point1, typename Point2>
0212 struct result_from_distance<pythagoras<CalculationType>, Point1, Point2>
0213 {
0214 private :
0215 typedef typename return_type<pythagoras<CalculationType>, Point1, Point2>::type return_type;
0216 public :
0217 template <typename T>
0218 static inline return_type apply(pythagoras<CalculationType> const& , T const& value)
0219 {
0220 return return_type(value);
0221 }
0222 };
0223
0224
0225
0226 template <typename CalculationType>
0227 struct tag<comparable::pythagoras<CalculationType> >
0228 {
0229 typedef strategy_tag_distance_point_point type;
0230 };
0231
0232
0233 template <typename CalculationType, typename P1, typename P2>
0234 struct return_type<comparable::pythagoras<CalculationType>, P1, P2>
0235 : comparable::pythagoras<CalculationType>::template calculation_type<P1, P2>
0236 {};
0237
0238
0239
0240
0241 template <typename CalculationType>
0242 struct comparable_type<comparable::pythagoras<CalculationType> >
0243 {
0244 typedef comparable::pythagoras<CalculationType> type;
0245 };
0246
0247
0248 template <typename CalculationType>
0249 struct get_comparable<comparable::pythagoras<CalculationType> >
0250 {
0251 typedef comparable::pythagoras<CalculationType> comparable_type;
0252 public :
0253 static inline comparable_type apply(comparable::pythagoras<CalculationType> const& )
0254 {
0255 return comparable_type();
0256 }
0257 };
0258
0259
0260 template <typename CalculationType, typename Point1, typename Point2>
0261 struct result_from_distance<comparable::pythagoras<CalculationType>, Point1, Point2>
0262 {
0263 private :
0264 typedef typename return_type<comparable::pythagoras<CalculationType>, Point1, Point2>::type return_type;
0265 public :
0266 template <typename T>
0267 static inline return_type apply(comparable::pythagoras<CalculationType> const& , T const& value)
0268 {
0269 return_type const v = value;
0270 return v * v;
0271 }
0272 };
0273
0274
0275 template <typename Point1, typename Point2>
0276 struct default_strategy
0277 <
0278 point_tag, point_tag, Point1, Point2, cartesian_tag, cartesian_tag
0279 >
0280 {
0281 typedef pythagoras<> type;
0282 };
0283
0284
0285 }
0286 #endif
0287
0288
0289 }}
0290
0291
0292 }}
0293
0294
0295 #endif