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_BOX_BOX_HPP
0021 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_BOX_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 <std::size_t I>
0047 struct compute_pythagoras_box_box
0048 {
0049 template <typename Box1, typename Box2, typename T>
0050 static inline void apply(Box1 const& box1, Box2 const& box2, T& result)
0051 {
0052 T const b1_min_coord =
0053 boost::numeric_cast<T>(geometry::get<min_corner, I-1>(box1));
0054 T const b1_max_coord =
0055 boost::numeric_cast<T>(geometry::get<max_corner, I-1>(box1));
0056
0057 T const b2_min_coord =
0058 boost::numeric_cast<T>(geometry::get<min_corner, I-1>(box2));
0059 T const b2_max_coord =
0060 boost::numeric_cast<T>(geometry::get<max_corner, I-1>(box2));
0061
0062 if ( b1_max_coord < b2_min_coord )
0063 {
0064 T diff = b2_min_coord - b1_max_coord;
0065 result += diff * diff;
0066 }
0067 if ( b1_min_coord > b2_max_coord )
0068 {
0069 T diff = b1_min_coord - b2_max_coord;
0070 result += diff * diff;
0071 }
0072
0073 compute_pythagoras_box_box<I-1>::apply(box1, box2, result);
0074 }
0075 };
0076
0077 template <>
0078 struct compute_pythagoras_box_box<0>
0079 {
0080 template <typename Box1, typename Box2, typename T>
0081 static inline void apply(Box1 const&, Box2 const&, T&)
0082 {
0083 }
0084 };
0085
0086 }
0087 #endif
0088
0089
0090 namespace comparable
0091 {
0092
0093
0094
0095
0096
0097
0098
0099
0100 template <typename CalculationType = void>
0101 class pythagoras_box_box
0102 {
0103 public :
0104
0105 template <typename Box1, typename Box2>
0106 struct calculation_type
0107 {
0108 typedef typename util::calculation_type::geometric::binary
0109 <
0110 Box1,
0111 Box2,
0112 CalculationType
0113 >::type type;
0114 };
0115
0116 template <typename Box1, typename Box2>
0117 static inline typename calculation_type<Box1, Box2>::type
0118 apply(Box1 const& box1, Box2 const& box2)
0119 {
0120 BOOST_CONCEPT_ASSERT
0121 ( (concepts::ConstPoint<typename point_type<Box1>::type>) );
0122 BOOST_CONCEPT_ASSERT
0123 ( (concepts::ConstPoint<typename point_type<Box2>::type>) );
0124
0125
0126
0127
0128 assert_dimension_equal<Box1, Box2>();
0129
0130 typename calculation_type<Box1, Box2>::type result(0);
0131
0132 detail::compute_pythagoras_box_box
0133 <
0134 dimension<Box1>::value
0135 >::apply(box1, box2, result);
0136
0137 return result;
0138 }
0139 };
0140
0141 }
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 template
0158 <
0159 typename CalculationType = void
0160 >
0161 class pythagoras_box_box
0162 {
0163 public :
0164
0165 template <typename Box1, typename Box2>
0166 struct calculation_type
0167 : util::calculation_type::geometric::binary
0168 <
0169 Box1,
0170 Box2,
0171 CalculationType,
0172 double,
0173 double
0174 >
0175 {};
0176
0177
0178
0179
0180
0181
0182
0183 template <typename Box1, typename Box2>
0184 static inline typename calculation_type<Box1, Box2>::type
0185 apply(Box1 const& box1, Box2 const& box2)
0186 {
0187
0188 return math::sqrt
0189 (
0190 boost::numeric_cast<typename calculation_type
0191 <
0192 Box1, Box2
0193 >::type>
0194 (
0195 comparable::pythagoras_box_box
0196 <
0197 CalculationType
0198 >::apply(box1, box2)
0199 )
0200 );
0201 }
0202 };
0203
0204
0205 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0206 namespace services
0207 {
0208
0209 template <typename CalculationType>
0210 struct tag<pythagoras_box_box<CalculationType> >
0211 {
0212 typedef strategy_tag_distance_box_box type;
0213 };
0214
0215
0216 template <typename CalculationType, typename Box1, typename Box2>
0217 struct return_type<distance::pythagoras_box_box<CalculationType>, Box1, Box2>
0218 : pythagoras_box_box<CalculationType>::template calculation_type<Box1, Box2>
0219 {};
0220
0221
0222 template <typename CalculationType>
0223 struct comparable_type<pythagoras_box_box<CalculationType> >
0224 {
0225 typedef comparable::pythagoras_box_box<CalculationType> type;
0226 };
0227
0228
0229 template <typename CalculationType>
0230 struct get_comparable<pythagoras_box_box<CalculationType> >
0231 {
0232 typedef comparable::pythagoras_box_box<CalculationType> comparable_type;
0233 public :
0234 static inline comparable_type
0235 apply(pythagoras_box_box<CalculationType> const& )
0236 {
0237 return comparable_type();
0238 }
0239 };
0240
0241
0242 template <typename CalculationType, typename Box1, typename Box2>
0243 struct result_from_distance<pythagoras_box_box<CalculationType>, Box1, Box2>
0244 {
0245 private:
0246 typedef typename return_type
0247 <
0248 pythagoras_box_box<CalculationType>, Box1, Box2
0249 >::type return_type;
0250 public:
0251 template <typename T>
0252 static inline return_type
0253 apply(pythagoras_box_box<CalculationType> const& , T const& value)
0254 {
0255 return return_type(value);
0256 }
0257 };
0258
0259
0260
0261 template <typename CalculationType>
0262 struct tag<comparable::pythagoras_box_box<CalculationType> >
0263 {
0264 typedef strategy_tag_distance_box_box type;
0265 };
0266
0267
0268 template <typename CalculationType, typename Box1, typename Box2>
0269 struct return_type<comparable::pythagoras_box_box<CalculationType>, Box1, Box2>
0270 : comparable::pythagoras_box_box
0271 <
0272 CalculationType
0273 >::template calculation_type<Box1, Box2>
0274 {};
0275
0276
0277
0278
0279 template <typename CalculationType>
0280 struct comparable_type<comparable::pythagoras_box_box<CalculationType> >
0281 {
0282 typedef comparable::pythagoras_box_box<CalculationType> type;
0283 };
0284
0285
0286 template <typename CalculationType>
0287 struct get_comparable<comparable::pythagoras_box_box<CalculationType> >
0288 {
0289 typedef comparable::pythagoras_box_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 Box1, typename Box2>
0299 struct result_from_distance
0300 <
0301 comparable::pythagoras_box_box<CalculationType>, Box1, Box2
0302 >
0303 {
0304 private :
0305 typedef typename return_type
0306 <
0307 comparable::pythagoras_box_box<CalculationType>, Box1, Box2
0308 >::type return_type;
0309 public :
0310 template <typename T>
0311 static inline return_type
0312 apply(comparable::pythagoras_box_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 BoxPoint1, typename BoxPoint2>
0322 struct default_strategy
0323 <
0324 box_tag, box_tag, BoxPoint1, BoxPoint2, cartesian_tag, cartesian_tag
0325 >
0326 {
0327 typedef pythagoras_box_box<> type;
0328 };
0329
0330
0331 }
0332 #endif
0333
0334
0335 }}
0336
0337
0338 }}
0339
0340
0341 #endif