File indexing completed on 2025-01-18 09:47:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_POLYGON_POINT_CONCEPT_HPP
0013 #define BOOST_POLYGON_POINT_CONCEPT_HPP
0014
0015 #include "isotropy.hpp"
0016 #include "point_traits.hpp"
0017
0018 namespace boost {
0019 namespace polygon {
0020
0021 struct point_concept {};
0022
0023 template <typename ConceptType>
0024 struct is_point_concept {
0025 typedef gtl_no type;
0026 };
0027
0028 template <>
0029 struct is_point_concept<point_concept> {
0030 typedef gtl_yes type;
0031 };
0032
0033 template <typename ConceptType>
0034 struct is_mutable_point_concept {
0035 typedef gtl_no type;
0036 };
0037
0038 template <>
0039 struct is_mutable_point_concept<point_concept> {
0040 typedef gtl_yes type;
0041 };
0042
0043 template <typename GeometryType, typename BoolType>
0044 struct point_coordinate_type_by_concept {
0045 typedef void type;
0046 };
0047
0048 template <typename GeometryType>
0049 struct point_coordinate_type_by_concept<GeometryType, gtl_yes> {
0050 typedef typename point_traits<GeometryType>::coordinate_type type;
0051 };
0052
0053 template <typename GeometryType>
0054 struct point_coordinate_type {
0055 typedef typename point_coordinate_type_by_concept<
0056 GeometryType,
0057 typename is_point_concept<
0058 typename geometry_concept<GeometryType>::type
0059 >::type
0060 >::type type;
0061 };
0062
0063 template <typename GeometryType, typename BoolType>
0064 struct point_difference_type_by_concept {
0065 typedef void type;
0066 };
0067
0068 template <typename GeometryType>
0069 struct point_difference_type_by_concept<GeometryType, gtl_yes> {
0070 typedef typename coordinate_traits<
0071 typename point_traits<GeometryType>::coordinate_type
0072 >::coordinate_difference type;
0073 };
0074
0075 template <typename GeometryType>
0076 struct point_difference_type {
0077 typedef typename point_difference_type_by_concept<
0078 GeometryType,
0079 typename is_point_concept<
0080 typename geometry_concept<GeometryType>::type
0081 >::type
0082 >::type type;
0083 };
0084
0085 template <typename GeometryType, typename BoolType>
0086 struct point_distance_type_by_concept {
0087 typedef void type;
0088 };
0089
0090 template <typename GeometryType>
0091 struct point_distance_type_by_concept<GeometryType, gtl_yes> {
0092 typedef typename coordinate_traits<
0093 typename point_coordinate_type<GeometryType>::type
0094 >::coordinate_distance type;
0095 };
0096
0097 template <typename GeometryType>
0098 struct point_distance_type {
0099 typedef typename point_distance_type_by_concept<
0100 GeometryType,
0101 typename is_point_concept<
0102 typename geometry_concept<GeometryType>::type
0103 >::type
0104 >::type type;
0105 };
0106
0107 struct y_pt_get : gtl_yes {};
0108
0109 template <typename PointType>
0110 typename enable_if<
0111 typename gtl_and<
0112 y_pt_get,
0113 typename is_point_concept<
0114 typename geometry_concept<PointType>::type
0115 >::type
0116 >::type,
0117 typename point_coordinate_type<PointType>::type
0118 >::type get(const PointType& point, orientation_2d orient) {
0119 return point_traits<PointType>::get(point, orient);
0120 }
0121
0122 struct y_pt_set : gtl_yes {};
0123
0124 template <typename PointType>
0125 typename enable_if<
0126 typename gtl_and<
0127 y_pt_set,
0128 typename is_mutable_point_concept<
0129 typename geometry_concept<PointType>::type
0130 >::type
0131 >::type,
0132 void
0133 >::type set(PointType& point, orientation_2d orient,
0134 typename point_mutable_traits<PointType>::coordinate_type value) {
0135 point_mutable_traits<PointType>::set(point, orient, value);
0136 }
0137
0138 struct y_pt_construct : gtl_yes {};
0139
0140 template <typename PointType>
0141 typename enable_if<
0142 typename gtl_and<
0143 y_pt_construct,
0144 typename is_mutable_point_concept<
0145 typename geometry_concept<PointType>::type
0146 >::type
0147 >::type,
0148 PointType>::type construct(
0149 typename point_mutable_traits<PointType>::coordinate_type x,
0150 typename point_mutable_traits<PointType>::coordinate_type y) {
0151 return point_mutable_traits<PointType>::construct(x, y);
0152 }
0153
0154 struct y_pt_assign : gtl_yes {};
0155
0156 template <typename PointType1, typename PointType2>
0157 typename enable_if<
0158 typename gtl_and_3<
0159 y_pt_assign,
0160 typename is_mutable_point_concept<
0161 typename geometry_concept<PointType1>::type
0162 >::type,
0163 typename is_point_concept<
0164 typename geometry_concept<PointType2>::type
0165 >::type
0166 >::type,
0167 PointType1>::type& assign(PointType1& lvalue, const PointType2& rvalue) {
0168 set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL));
0169 set(lvalue, VERTICAL, get(rvalue, VERTICAL));
0170 return lvalue;
0171 }
0172
0173 struct y_p_x : gtl_yes {};
0174
0175 template <typename PointType>
0176 typename enable_if<
0177 typename gtl_and<
0178 y_p_x,
0179 typename is_point_concept<
0180 typename geometry_concept<PointType>::type
0181 >::type
0182 >::type,
0183 typename point_coordinate_type<PointType>::type
0184 >::type x(const PointType& point) {
0185 return get(point, HORIZONTAL);
0186 }
0187
0188 struct y_p_y : gtl_yes {};
0189
0190 template <typename PointType>
0191 typename enable_if<
0192 typename gtl_and<
0193 y_p_y,
0194 typename is_point_concept<
0195 typename geometry_concept<PointType>::type
0196 >::type
0197 >::type,
0198 typename point_coordinate_type<PointType>::type
0199 >::type y(const PointType& point) {
0200 return get(point, VERTICAL);
0201 }
0202
0203 struct y_p_sx : gtl_yes {};
0204
0205 template <typename PointType>
0206 typename enable_if<
0207 typename gtl_and<
0208 y_p_sx,
0209 typename is_mutable_point_concept<
0210 typename geometry_concept<PointType>::type
0211 >::type
0212 >::type,
0213 void>::type x(PointType& point,
0214 typename point_mutable_traits<PointType>::coordinate_type value) {
0215 set(point, HORIZONTAL, value);
0216 }
0217
0218 struct y_p_sy : gtl_yes {};
0219
0220 template <typename PointType>
0221 typename enable_if<
0222 typename gtl_and<
0223 y_p_sy,
0224 typename is_mutable_point_concept<
0225 typename geometry_concept<PointType>::type
0226 >::type
0227 >::type,
0228 void>::type y(PointType& point,
0229 typename point_mutable_traits<PointType>::coordinate_type value) {
0230 set(point, VERTICAL, value);
0231 }
0232
0233 struct y_pt_equiv : gtl_yes {};
0234
0235 template <typename PointType1, typename PointType2>
0236 typename enable_if<
0237 typename gtl_and_3<
0238 y_pt_equiv,
0239 typename is_point_concept<
0240 typename geometry_concept<PointType1>::type
0241 >::type,
0242 typename is_point_concept<
0243 typename geometry_concept<PointType2>::type
0244 >::type
0245 >::type,
0246 bool>::type equivalence(
0247 const PointType1& point1, const PointType2& point2) {
0248 return (x(point1) == x(point2)) && (y(point1) == y(point2));
0249 }
0250
0251 struct y_pt_man_dist : gtl_yes {};
0252
0253 template <typename PointType1, typename PointType2>
0254 typename enable_if<
0255 typename gtl_and_3<
0256 y_pt_man_dist,
0257 typename is_point_concept<
0258 typename geometry_concept<PointType1>::type
0259 >::type,
0260 typename is_point_concept<
0261 typename geometry_concept<PointType2>::type
0262 >::type
0263 >::type,
0264 typename point_difference_type<PointType1>::type>::type
0265 manhattan_distance(const PointType1& point1, const PointType2& point2) {
0266 return euclidean_distance(point1, point2, HORIZONTAL) +
0267 euclidean_distance(point1, point2, VERTICAL);
0268 }
0269
0270 struct y_pt_ed1 : gtl_yes {};
0271
0272 template <typename PointType1, typename PointType2>
0273 typename enable_if<
0274 typename gtl_and_3<
0275 y_pt_ed1,
0276 typename is_point_concept<
0277 typename geometry_concept<PointType1>::type
0278 >::type,
0279 typename is_point_concept<
0280 typename geometry_concept<PointType2>::type
0281 >::type
0282 >::type,
0283 typename point_difference_type<PointType1>::type>::type
0284 euclidean_distance(
0285 const PointType1& point1,
0286 const PointType2& point2,
0287 orientation_2d orient) {
0288 typename point_difference_type<PointType1>::type dif =
0289 get(point1, orient) - get(point2, orient);
0290 return (dif < 0) ? -dif : dif;
0291 }
0292
0293 struct y_pt_eds : gtl_yes {};
0294
0295 template <typename PointType1, typename PointType2>
0296 typename enable_if<
0297 typename gtl_and_3<
0298 y_pt_eds,
0299 typename is_point_concept<
0300 typename geometry_concept<PointType1>::type
0301 >::type,
0302 typename is_point_concept<
0303 typename geometry_concept<PointType2>::type
0304 >::type
0305 >::type,
0306 typename point_difference_type<PointType1>::type>::type
0307 distance_squared(const PointType1& point1, const PointType2& point2) {
0308 typename point_difference_type<PointType1>::type dx =
0309 euclidean_distance(point1, point2, HORIZONTAL);
0310 typename point_difference_type<PointType1>::type dy =
0311 euclidean_distance(point1, point2, VERTICAL);
0312 dx *= dx;
0313 dy *= dy;
0314 return dx + dy;
0315 }
0316
0317 struct y_pt_ed2 : gtl_yes {};
0318
0319 template <typename PointType1, typename PointType2>
0320 typename enable_if<
0321 typename gtl_and_3<
0322 y_pt_ed2,
0323 typename is_point_concept<
0324 typename geometry_concept<PointType1>::type
0325 >::type,
0326 typename is_point_concept<
0327 typename geometry_concept<PointType2>::type
0328 >::type
0329 >::type,
0330 typename point_distance_type<PointType1>::type>::type
0331 euclidean_distance(const PointType1& point1, const PointType2& point2) {
0332 return (std::sqrt)(
0333 static_cast<double>(distance_squared(point1, point2)));
0334 }
0335
0336 struct y_pt_convolve : gtl_yes {};
0337
0338 template <typename PointType1, typename PointType2>
0339 typename enable_if<
0340 typename gtl_and_3<
0341 y_pt_convolve,
0342 typename is_mutable_point_concept<
0343 typename geometry_concept<PointType1>::type
0344 >::type,
0345 typename is_point_concept<
0346 typename geometry_concept<PointType2>::type
0347 >::type
0348 >::type,
0349 PointType1>::type& convolve(PointType1& lvalue, const PointType2& rvalue) {
0350 x(lvalue, x(lvalue) + x(rvalue));
0351 y(lvalue, y(lvalue) + y(rvalue));
0352 return lvalue;
0353 }
0354
0355 struct y_pt_deconvolve : gtl_yes {};
0356
0357 template <typename PointType1, typename PointType2>
0358 typename enable_if<
0359 typename gtl_and_3<
0360 y_pt_deconvolve,
0361 typename is_mutable_point_concept<
0362 typename geometry_concept<PointType1>::type
0363 >::type,
0364 typename is_point_concept<
0365 typename geometry_concept<PointType2>::type
0366 >::type
0367 >::type,
0368 PointType1>::type& deconvolve(PointType1& lvalue, const PointType2& rvalue) {
0369 x(lvalue, x(lvalue) - x(rvalue));
0370 y(lvalue, y(lvalue) - y(rvalue));
0371 return lvalue;
0372 }
0373
0374 struct y_pt_scale_up : gtl_yes {};
0375
0376 template <typename PointType, typename CType>
0377 typename enable_if<
0378 typename gtl_and<
0379 y_pt_scale_up,
0380 typename is_mutable_point_concept<
0381 typename geometry_concept<PointType>::type
0382 >::type
0383 >::type,
0384 PointType>::type& scale_up(PointType& point, CType factor) {
0385 typedef typename point_coordinate_type<PointType>::type Unit;
0386 x(point, x(point) * (Unit)factor);
0387 y(point, y(point) * (Unit)factor);
0388 return point;
0389 }
0390
0391 struct y_pt_scale_down : gtl_yes {};
0392
0393 template <typename PointType, typename CType>
0394 typename enable_if<
0395 typename gtl_and<
0396 y_pt_scale_down,
0397 typename is_mutable_point_concept<
0398 typename geometry_concept<PointType>::type
0399 >::type
0400 >::type,
0401 PointType>::type& scale_down(PointType& point, CType factor) {
0402 typedef typename point_coordinate_type<PointType>::type Unit;
0403 typedef typename coordinate_traits<Unit>::coordinate_distance dt;
0404 x(point, scaling_policy<Unit>::round((dt)(x(point)) / (dt)factor));
0405 y(point, scaling_policy<Unit>::round((dt)(y(point)) / (dt)factor));
0406 return point;
0407 }
0408
0409 struct y_pt_scale : gtl_yes {};
0410
0411 template <typename PointType, typename ScaleType>
0412 typename enable_if<
0413 typename gtl_and<
0414 y_pt_scale,
0415 typename is_mutable_point_concept<
0416 typename geometry_concept<PointType>::type
0417 >::type
0418 >::type,
0419 PointType>::type& scale(PointType& point, const ScaleType& scaling) {
0420 typedef typename point_coordinate_type<PointType>::type Unit;
0421 Unit x_coord(x(point));
0422 Unit y_coord(y(point));
0423 scaling.scale(x_coord, y_coord);
0424 x(point, x_coord);
0425 y(point, y_coord);
0426 return point;
0427 }
0428
0429 struct y_pt_transform : gtl_yes {};
0430
0431 template <typename PointType, typename TransformType>
0432 typename enable_if<
0433 typename gtl_and<
0434 y_pt_transform,
0435 typename is_mutable_point_concept<
0436 typename geometry_concept<PointType>::type
0437 >::type
0438 >::type,
0439 PointType>::type& transform(PointType& point, const TransformType& transform) {
0440 typedef typename point_coordinate_type<PointType>::type Unit;
0441 Unit x_coord(x(point));
0442 Unit y_coord(y(point));
0443 transform.transform(x_coord, y_coord);
0444 x(point, x_coord);
0445 y(point, y_coord);
0446 return point;
0447 }
0448
0449 struct y_pt_move : gtl_yes {};
0450
0451 template <typename PointType>
0452 typename enable_if<
0453 typename gtl_and<
0454 y_pt_move,
0455 typename is_mutable_point_concept<
0456 typename geometry_concept<PointType>::type
0457 >::type
0458 >::type,
0459 PointType>::type& move(PointType& point, orientation_2d orient,
0460 typename point_coordinate_type<PointType>::type displacement) {
0461 typedef typename point_coordinate_type<PointType>::type Unit;
0462 Unit coord = get(point, orient);
0463 set(point, orient, coord + displacement);
0464 return point;
0465 }
0466 }
0467 }
0468
0469 #endif