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
0020 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_POINT_BOX_HPP
0021 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_POINT_BOX_HPP
0022
0023
0024 #include <boost/geometry/core/access.hpp>
0025 #include <boost/geometry/core/point_type.hpp>
0026
0027 #include <boost/geometry/geometries/concepts/point_concept.hpp>
0028
0029 #include <boost/geometry/strategies/distance.hpp>
0030
0031 #include <boost/geometry/util/math.hpp>
0032 #include <boost/geometry/util/calculation_type.hpp>
0033
0034
0035
0036 namespace boost { namespace geometry
0037 {
0038
0039 namespace strategy { namespace distance
0040 {
0041
0042 #ifndef DOXYGEN_NO_DETAIL
0043 namespace detail
0044 {
0045
0046 template <size_t I>
0047 struct compute_pythagoras_point_box
0048 {
0049 template <typename Point, typename Box, typename T>
0050 static inline void apply(Point const& point, Box const& box, T& result)
0051 {
0052 T const p_coord = boost::numeric_cast<T>(geometry::get<I-1>(point));
0053 T const b_min_coord =
0054 boost::numeric_cast<T>(geometry::get<min_corner, I-1>(box));
0055 T const b_max_coord =
0056 boost::numeric_cast<T>(geometry::get<max_corner, I-1>(box));
0057
0058 if ( p_coord < b_min_coord )
0059 {
0060 T diff = b_min_coord - p_coord;
0061 result += diff * diff;
0062 }
0063 if ( p_coord > b_max_coord )
0064 {
0065 T diff = p_coord - b_max_coord;
0066 result += diff * diff;
0067 }
0068
0069 compute_pythagoras_point_box<I-1>::apply(point, box, result);
0070 }
0071 };
0072
0073 template <>
0074 struct compute_pythagoras_point_box<0>
0075 {
0076 template <typename Point, typename Box, typename T>
0077 static inline void apply(Point const&, Box const&, T&)
0078 {
0079 }
0080 };
0081
0082
0083 }
0084 #endif
0085
0086
0087 namespace comparable
0088 {
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098 template <typename CalculationType = void>
0099 class pythagoras_point_box
0100 {
0101 public :
0102
0103 template <typename Point, typename Box>
0104 struct calculation_type
0105 {
0106 typedef typename util::calculation_type::geometric::binary
0107 <
0108 Point, Box, CalculationType
0109 >::type type;
0110 };
0111
0112 template <typename Point, typename Box>
0113 static inline typename calculation_type<Point, Box>::type
0114 apply(Point const& point, Box const& box)
0115 {
0116 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point>) );
0117 BOOST_CONCEPT_ASSERT
0118 ( (concepts::ConstPoint<typename point_type<Box>::type>) );
0119
0120
0121
0122
0123 assert_dimension_equal<Point, Box>();
0124
0125 typename calculation_type<Point, Box>::type result(0);
0126
0127 detail::compute_pythagoras_point_box
0128 <
0129 dimension<Point>::value
0130 >::apply(point, box, result);
0131
0132 return result;
0133 }
0134 };
0135
0136 }
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152 template
0153 <
0154 typename CalculationType = void
0155 >
0156 class pythagoras_point_box
0157 {
0158 public :
0159
0160 template <typename Point, typename Box>
0161 struct calculation_type
0162 : util::calculation_type::geometric::binary
0163 <
0164 Point,
0165 Box,
0166 CalculationType,
0167 double,
0168 double
0169 >
0170 {};
0171
0172
0173
0174
0175
0176
0177
0178 template <typename Point, typename Box>
0179 static inline typename calculation_type<Point, Box>::type
0180 apply(Point const& point, Box const& box)
0181 {
0182
0183 return math::sqrt
0184 (
0185 boost::numeric_cast<typename calculation_type
0186 <
0187 Point, Box
0188 >::type>
0189 (
0190 comparable::pythagoras_point_box
0191 <
0192 CalculationType
0193 >::apply(point, box)
0194 )
0195 );
0196 }
0197 };
0198
0199
0200 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0201 namespace services
0202 {
0203
0204 template <typename CalculationType>
0205 struct tag<pythagoras_point_box<CalculationType> >
0206 {
0207 typedef strategy_tag_distance_point_box type;
0208 };
0209
0210
0211 template <typename CalculationType, typename Point, typename Box>
0212 struct return_type<distance::pythagoras_point_box<CalculationType>, Point, Box>
0213 : pythagoras_point_box
0214 <
0215 CalculationType
0216 >::template calculation_type<Point, Box>
0217 {};
0218
0219
0220 template <typename CalculationType>
0221 struct comparable_type<pythagoras_point_box<CalculationType> >
0222 {
0223 typedef comparable::pythagoras_point_box<CalculationType> type;
0224 };
0225
0226
0227 template <typename CalculationType>
0228 struct get_comparable<pythagoras_point_box<CalculationType> >
0229 {
0230 typedef comparable::pythagoras_point_box<CalculationType> comparable_type;
0231 public :
0232 static inline comparable_type
0233 apply(pythagoras_point_box<CalculationType> const& )
0234 {
0235 return comparable_type();
0236 }
0237 };
0238
0239
0240 template <typename CalculationType, typename Point, typename Box>
0241 struct result_from_distance<pythagoras_point_box<CalculationType>, Point, Box>
0242 {
0243 private :
0244 typedef typename return_type
0245 <
0246 pythagoras_point_box<CalculationType>, Point, Box
0247 >::type return_type;
0248 public :
0249 template <typename T>
0250 static inline return_type
0251 apply(pythagoras_point_box<CalculationType> const& , T const& value)
0252 {
0253 return return_type(value);
0254 }
0255 };
0256
0257
0258
0259 template <typename CalculationType>
0260 struct tag<comparable::pythagoras_point_box<CalculationType> >
0261 {
0262 typedef strategy_tag_distance_point_box type;
0263 };
0264
0265
0266 template <typename CalculationType, typename Point, typename Box>
0267 struct return_type
0268 <
0269 comparable::pythagoras_point_box<CalculationType>, Point, Box
0270 > : comparable::pythagoras_point_box
0271 <
0272 CalculationType
0273 >::template calculation_type<Point, Box>
0274 {};
0275
0276
0277
0278
0279 template <typename CalculationType>
0280 struct comparable_type<comparable::pythagoras_point_box<CalculationType> >
0281 {
0282 typedef comparable::pythagoras_point_box<CalculationType> type;
0283 };
0284
0285
0286 template <typename CalculationType>
0287 struct get_comparable<comparable::pythagoras_point_box<CalculationType> >
0288 {
0289 typedef comparable::pythagoras_point_box<CalculationType> comparable_type;
0290 public :
0291 static inline comparable_type apply(comparable_type const& )
0292 {
0293 return comparable_type();
0294 }
0295 };
0296
0297
0298 template <typename CalculationType, typename Point, typename Box>
0299 struct result_from_distance
0300 <
0301 comparable::pythagoras_point_box<CalculationType>, Point, Box
0302 >
0303 {
0304 private :
0305 typedef typename return_type
0306 <
0307 comparable::pythagoras_point_box<CalculationType>, Point, Box
0308 >::type return_type;
0309 public :
0310 template <typename T>
0311 static inline return_type
0312 apply(comparable::pythagoras_point_box<CalculationType> const& ,
0313 T const& value)
0314 {
0315 return_type const v = value;
0316 return v * v;
0317 }
0318 };
0319
0320
0321 template <typename Point, typename BoxPoint>
0322 struct default_strategy
0323 <
0324 point_tag, box_tag, Point, BoxPoint, cartesian_tag, cartesian_tag
0325 >
0326 {
0327 typedef pythagoras_point_box<> type;
0328 };
0329
0330 template <typename BoxPoint, typename Point>
0331 struct default_strategy
0332 <
0333 box_tag, point_tag, BoxPoint, Point, cartesian_tag, cartesian_tag
0334 >
0335 {
0336 typedef typename default_strategy
0337 <
0338 point_tag, box_tag, Point, BoxPoint, cartesian_tag, cartesian_tag
0339 >::type type;
0340 };
0341
0342
0343 }
0344 #endif
0345
0346
0347 }}
0348
0349
0350 }}
0351
0352
0353 #endif