File indexing completed on 2025-01-18 09:48:02
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_POLYGON_POLYGON_TRAITS_HPP
0009 #define BOOST_POLYGON_POLYGON_TRAITS_HPP
0010 namespace boost { namespace polygon{
0011
0012 template <typename T, typename enable = gtl_yes>
0013 struct polygon_90_traits {
0014 typedef typename T::coordinate_type coordinate_type;
0015 typedef typename T::compact_iterator_type compact_iterator_type;
0016
0017
0018 static inline compact_iterator_type begin_compact(const T& t) {
0019 return t.begin_compact();
0020 }
0021
0022
0023 static inline compact_iterator_type end_compact(const T& t) {
0024 return t.end_compact();
0025 }
0026
0027
0028 static inline std::size_t size(const T& t) {
0029 return t.size();
0030 }
0031
0032
0033 static inline winding_direction winding(const T&) {
0034 return unknown_winding;
0035 }
0036 };
0037
0038 template <typename T>
0039 struct polygon_traits_general {
0040 typedef typename T::coordinate_type coordinate_type;
0041 typedef typename T::iterator_type iterator_type;
0042 typedef typename T::point_type point_type;
0043
0044
0045 static inline iterator_type begin_points(const T& t) {
0046 return t.begin();
0047 }
0048
0049
0050 static inline iterator_type end_points(const T& t) {
0051 return t.end();
0052 }
0053
0054
0055 static inline std::size_t size(const T& t) {
0056 return t.size();
0057 }
0058
0059
0060 static inline winding_direction winding(const T&) {
0061 return unknown_winding;
0062 }
0063 };
0064
0065 template <typename T>
0066 struct polygon_traits_90 {
0067 typedef typename polygon_90_traits<T>::coordinate_type coordinate_type;
0068 typedef iterator_compact_to_points<typename polygon_90_traits<T>::compact_iterator_type, point_data<coordinate_type> > iterator_type;
0069 typedef point_data<coordinate_type> point_type;
0070
0071
0072 static inline iterator_type begin_points(const T& t) {
0073 return iterator_type(polygon_90_traits<T>::begin_compact(t),
0074 polygon_90_traits<T>::end_compact(t));
0075 }
0076
0077
0078 static inline iterator_type end_points(const T& t) {
0079 return iterator_type(polygon_90_traits<T>::end_compact(t),
0080 polygon_90_traits<T>::end_compact(t));
0081 }
0082
0083
0084 static inline std::size_t size(const T& t) {
0085 return polygon_90_traits<T>::size(t);
0086 }
0087
0088
0089 static inline winding_direction winding(const T& t) {
0090 return polygon_90_traits<T>::winding(t);
0091 }
0092 };
0093
0094 #ifndef BOOST_VERY_LITTLE_SFINAE
0095
0096 template <typename T, typename enable = gtl_yes>
0097 struct polygon_traits {};
0098
0099 template <typename T>
0100 struct polygon_traits<T,
0101 typename gtl_or_4<
0102 typename gtl_same_type<typename geometry_concept<T>::type, polygon_concept>::type,
0103 typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_concept>::type,
0104 typename gtl_same_type<typename geometry_concept<T>::type, polygon_with_holes_concept>::type,
0105 typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_with_holes_concept>::type
0106 >::type> : public polygon_traits_general<T> {};
0107
0108 template <typename T>
0109 struct polygon_traits< T,
0110 typename gtl_or<
0111 typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
0112 typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type
0113 >::type > : public polygon_traits_90<T> {};
0114
0115 #else
0116
0117 template <typename T, typename T_IF, typename T_ELSE>
0118 struct gtl_ifelse {};
0119 template <typename T_IF, typename T_ELSE>
0120 struct gtl_ifelse<gtl_no, T_IF, T_ELSE> {
0121 typedef T_ELSE type;
0122 };
0123 template <typename T_IF, typename T_ELSE>
0124 struct gtl_ifelse<gtl_yes, T_IF, T_ELSE> {
0125 typedef T_IF type;
0126 };
0127
0128 template <typename T, typename enable = gtl_yes>
0129 struct polygon_traits {};
0130
0131 template <typename T>
0132 struct polygon_traits<T, typename gtl_or<typename gtl_or_4<
0133 typename gtl_same_type<typename geometry_concept<T>::type, polygon_concept>::type,
0134 typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_concept>::type,
0135 typename gtl_same_type<typename geometry_concept<T>::type, polygon_with_holes_concept>::type,
0136 typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_with_holes_concept>::type
0137 >::type, typename gtl_or<
0138 typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
0139 typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type
0140 >::type>::type > : public gtl_ifelse<typename gtl_or<
0141 typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
0142 typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type >::type,
0143 polygon_traits_90<T>,
0144 polygon_traits_general<T> >::type {
0145 };
0146
0147 #endif
0148
0149 template <typename T, typename enable = void>
0150 struct polygon_with_holes_traits {
0151 typedef typename T::iterator_holes_type iterator_holes_type;
0152 typedef typename T::hole_type hole_type;
0153
0154
0155 static inline iterator_holes_type begin_holes(const T& t) {
0156 return t.begin_holes();
0157 }
0158
0159
0160 static inline iterator_holes_type end_holes(const T& t) {
0161 return t.end_holes();
0162 }
0163
0164
0165 static inline std::size_t size_holes(const T& t) {
0166 return t.size_holes();
0167 }
0168 };
0169
0170 template <typename T, typename enable = void>
0171 struct polygon_90_mutable_traits {
0172
0173
0174 template <typename iT>
0175 static inline T& set_compact(T& t, iT input_begin, iT input_end) {
0176 t.set_compact(input_begin, input_end);
0177 return t;
0178 }
0179
0180 };
0181
0182 template <typename T, typename enable = void>
0183 struct polygon_mutable_traits {
0184
0185
0186 template <typename iT>
0187 static inline T& set_points(T& t, iT input_begin, iT input_end) {
0188 t.set(input_begin, input_end);
0189 return t;
0190 }
0191
0192 };
0193
0194 template <typename T, typename enable = void>
0195 struct polygon_with_holes_mutable_traits {
0196
0197
0198 template <typename iT>
0199 static inline T& set_holes(T& t, iT inputBegin, iT inputEnd) {
0200 t.set_holes(inputBegin, inputEnd);
0201 return t;
0202 }
0203
0204 };
0205 }
0206 }
0207 #include "isotropy.hpp"
0208
0209
0210 #include "point_data.hpp"
0211 #include "point_traits.hpp"
0212 #include "point_concept.hpp"
0213
0214
0215 #include "interval_data.hpp"
0216 #include "interval_traits.hpp"
0217 #include "interval_concept.hpp"
0218
0219
0220 #include "rectangle_data.hpp"
0221 #include "rectangle_traits.hpp"
0222 #include "rectangle_concept.hpp"
0223
0224
0225 #include "detail/iterator_points_to_compact.hpp"
0226 #include "detail/iterator_compact_to_points.hpp"
0227
0228
0229 #include "polygon_45_data.hpp"
0230 #include "polygon_data.hpp"
0231 #include "polygon_90_data.hpp"
0232 #include "polygon_90_with_holes_data.hpp"
0233 #include "polygon_45_with_holes_data.hpp"
0234 #include "polygon_with_holes_data.hpp"
0235
0236 namespace boost { namespace polygon{
0237 struct polygon_concept {};
0238 struct polygon_with_holes_concept {};
0239 struct polygon_45_concept {};
0240 struct polygon_45_with_holes_concept {};
0241 struct polygon_90_concept {};
0242 struct polygon_90_with_holes_concept {};
0243
0244
0245 template <typename T>
0246 struct is_polygon_90_type {
0247 typedef typename geometry_concept<T>::type GC;
0248 typedef typename gtl_same_type<polygon_90_concept, GC>::type type;
0249 };
0250
0251 template <typename T>
0252 struct is_polygon_45_type {
0253 typedef typename geometry_concept<T>::type GC;
0254 typedef typename gtl_or<typename is_polygon_90_type<T>::type,
0255 typename gtl_same_type<polygon_45_concept, GC>::type>::type type;
0256 };
0257
0258 template <typename T>
0259 struct is_polygon_type {
0260 typedef typename geometry_concept<T>::type GC;
0261 typedef typename gtl_or<typename is_polygon_45_type<T>::type,
0262 typename gtl_same_type<polygon_concept, GC>::type>::type type;
0263 };
0264
0265 template <typename T>
0266 struct is_polygon_90_with_holes_type {
0267 typedef typename geometry_concept<T>::type GC;
0268 typedef typename gtl_or<typename is_polygon_90_type<T>::type,
0269 typename gtl_same_type<polygon_90_with_holes_concept, GC>::type>::type type;
0270 };
0271
0272 template <typename T>
0273 struct is_polygon_45_with_holes_type {
0274 typedef typename geometry_concept<T>::type GC;
0275 typedef typename gtl_or_3<typename is_polygon_90_with_holes_type<T>::type,
0276 typename is_polygon_45_type<T>::type,
0277 typename gtl_same_type<polygon_45_with_holes_concept, GC>::type>::type type;
0278 };
0279
0280 template <typename T>
0281 struct is_polygon_with_holes_type {
0282 typedef typename geometry_concept<T>::type GC;
0283 typedef typename gtl_or_3<typename is_polygon_45_with_holes_type<T>::type,
0284 typename is_polygon_type<T>::type,
0285 typename gtl_same_type<polygon_with_holes_concept, GC>::type>::type type;
0286 };
0287
0288 template <typename T>
0289 struct is_mutable_polygon_90_type {
0290 typedef typename geometry_concept<T>::type GC;
0291 typedef typename gtl_same_type<polygon_90_concept, GC>::type type;
0292 };
0293
0294 template <typename T>
0295 struct is_mutable_polygon_45_type {
0296 typedef typename geometry_concept<T>::type GC;
0297 typedef typename gtl_same_type<polygon_45_concept, GC>::type type;
0298 };
0299
0300 template <typename T>
0301 struct is_mutable_polygon_type {
0302 typedef typename geometry_concept<T>::type GC;
0303 typedef typename gtl_same_type<polygon_concept, GC>::type type;
0304 };
0305
0306 template <typename T>
0307 struct is_mutable_polygon_90_with_holes_type {
0308 typedef typename geometry_concept<T>::type GC;
0309 typedef typename gtl_same_type<polygon_90_with_holes_concept, GC>::type type;
0310 };
0311
0312 template <typename T>
0313 struct is_mutable_polygon_45_with_holes_type {
0314 typedef typename geometry_concept<T>::type GC;
0315 typedef typename gtl_same_type<polygon_45_with_holes_concept, GC>::type type;
0316 };
0317
0318 template <typename T>
0319 struct is_mutable_polygon_with_holes_type {
0320 typedef typename geometry_concept<T>::type GC;
0321 typedef typename gtl_same_type<polygon_with_holes_concept, GC>::type type;
0322 };
0323
0324 template <typename T>
0325 struct is_any_mutable_polygon_with_holes_type {
0326 typedef typename gtl_or_3<typename is_mutable_polygon_90_with_holes_type<T>::type,
0327 typename is_mutable_polygon_45_with_holes_type<T>::type,
0328 typename is_mutable_polygon_with_holes_type<T>::type>::type type;
0329 };
0330 template <typename T>
0331 struct is_any_mutable_polygon_without_holes_type {
0332 typedef typename gtl_or_3<
0333 typename is_mutable_polygon_90_type<T>::type,
0334 typename is_mutable_polygon_45_type<T>::type,
0335 typename is_mutable_polygon_type<T>::type>::type type; };
0336
0337 template <typename T>
0338 struct is_any_mutable_polygon_type {
0339 typedef typename gtl_or<typename is_any_mutable_polygon_with_holes_type<T>::type,
0340 typename is_any_mutable_polygon_without_holes_type<T>::type>::type type;
0341 };
0342
0343 template <typename T>
0344 struct polygon_from_polygon_with_holes_type {};
0345 template <>
0346 struct polygon_from_polygon_with_holes_type<polygon_with_holes_concept> { typedef polygon_concept type; };
0347 template <>
0348 struct polygon_from_polygon_with_holes_type<polygon_45_with_holes_concept> { typedef polygon_45_concept type; };
0349 template <>
0350 struct polygon_from_polygon_with_holes_type<polygon_90_with_holes_concept> { typedef polygon_90_concept type; };
0351
0352 template <>
0353 struct geometry_domain<polygon_45_concept> { typedef forty_five_domain type; };
0354 template <>
0355 struct geometry_domain<polygon_45_with_holes_concept> { typedef forty_five_domain type; };
0356 template <>
0357 struct geometry_domain<polygon_90_concept> { typedef manhattan_domain type; };
0358 template <>
0359 struct geometry_domain<polygon_90_with_holes_concept> { typedef manhattan_domain type; };
0360
0361 template <typename domain_type, typename coordinate_type>
0362 struct distance_type_by_domain { typedef typename coordinate_traits<coordinate_type>::coordinate_distance type; };
0363 template <typename coordinate_type>
0364 struct distance_type_by_domain<manhattan_domain, coordinate_type> {
0365 typedef typename coordinate_traits<coordinate_type>::coordinate_difference type; };
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375 template <typename T, typename iT>
0376 typename enable_if <typename is_any_mutable_polygon_type<T>::type, T>::type &
0377 set_points(T& t, iT begin_points, iT end_points) {
0378 polygon_mutable_traits<T>::set_points(t, begin_points, end_points);
0379 return t;
0380 }
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390 template <typename T, typename iT>
0391 typename enable_if <typename gtl_or<
0392 typename is_mutable_polygon_90_type<T>::type,
0393 typename is_mutable_polygon_90_with_holes_type<T>::type>::type, T>::type &
0394 set_compact(T& t, iT begin_compact_coordinates, iT end_compact_coordinates) {
0395 polygon_90_mutable_traits<T>::set_compact(t, begin_compact_coordinates, end_compact_coordinates);
0396 return t;
0397 }
0398
0399
0400 template <typename T, typename iT>
0401 typename enable_if< typename gtl_and <
0402 typename is_any_mutable_polygon_with_holes_type<T>::type,
0403 typename gtl_different_type<typename geometry_domain<typename geometry_concept<T>::type>::type,
0404 manhattan_domain>::type>::type,
0405 T>::type &
0406 set_compact(T& t, iT begin_compact_coordinates, iT end_compact_coordinates) {
0407 iterator_compact_to_points<iT, point_data<typename polygon_traits<T>::coordinate_type> >
0408 itrb(begin_compact_coordinates, end_compact_coordinates),
0409 itre(end_compact_coordinates, end_compact_coordinates);
0410 return set_points(t, itrb, itre);
0411 }
0412
0413
0414 template <typename T, typename iT>
0415 typename enable_if <typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type &
0416 set_holes(T& t, iT begin_holes, iT end_holes) {
0417 polygon_with_holes_mutable_traits<T>::set_holes(t, begin_holes, end_holes);
0418 return t;
0419 }
0420
0421
0422 template <typename T>
0423 typename polygon_90_traits<T>::compact_iterator_type
0424 begin_compact(const T& polygon,
0425 typename enable_if<
0426 typename gtl_and <typename is_polygon_with_holes_type<T>::type,
0427 typename gtl_same_type<typename geometry_domain<typename geometry_concept<T>::type>::type,
0428 manhattan_domain>::type>::type>::type * = 0
0429 ) {
0430 return polygon_90_traits<T>::begin_compact(polygon);
0431 }
0432
0433
0434 template <typename T>
0435 typename polygon_90_traits<T>::compact_iterator_type
0436 end_compact(const T& polygon,
0437 typename enable_if<
0438 typename gtl_and <typename is_polygon_with_holes_type<T>::type,
0439 typename gtl_same_type<typename geometry_domain<typename geometry_concept<T>::type>::type,
0440 manhattan_domain>::type>::type>::type * = 0
0441 ) {
0442 return polygon_90_traits<T>::end_compact(polygon);
0443 }
0444
0445
0446 template <typename T>
0447 typename enable_if < typename gtl_if<
0448 typename is_polygon_with_holes_type<T>::type>::type,
0449 typename polygon_traits<T>::iterator_type>::type
0450 begin_points(const T& polygon) {
0451 return polygon_traits<T>::begin_points(polygon);
0452 }
0453
0454
0455 template <typename T>
0456 typename enable_if < typename gtl_if<
0457 typename is_polygon_with_holes_type<T>::type>::type,
0458 typename polygon_traits<T>::iterator_type>::type
0459 end_points(const T& polygon) {
0460 return polygon_traits<T>::end_points(polygon);
0461 }
0462
0463
0464 template <typename T>
0465 typename enable_if <typename is_polygon_with_holes_type<T>::type,
0466 std::size_t>::type
0467 size(const T& polygon) {
0468 return polygon_traits<T>::size(polygon);
0469 }
0470
0471
0472 template <typename T>
0473 typename enable_if < typename gtl_if<
0474 typename is_polygon_with_holes_type<T>::type>::type,
0475 typename polygon_with_holes_traits<T>::iterator_holes_type>::type
0476 begin_holes(const T& polygon) {
0477 return polygon_with_holes_traits<T>::begin_holes(polygon);
0478 }
0479
0480
0481 template <typename T>
0482 typename enable_if < typename gtl_if<
0483 typename is_polygon_with_holes_type<T>::type>::type,
0484 typename polygon_with_holes_traits<T>::iterator_holes_type>::type
0485 end_holes(const T& polygon) {
0486 return polygon_with_holes_traits<T>::end_holes(polygon);
0487 }
0488
0489
0490 template <typename T>
0491 typename enable_if <typename is_polygon_with_holes_type<T>::type,
0492 std::size_t>::type
0493 size_holes(const T& polygon) {
0494 return polygon_with_holes_traits<T>::size_holes(polygon);
0495 }
0496
0497
0498 template <typename T1, typename T2>
0499 typename enable_if<
0500 typename gtl_and< typename is_mutable_polygon_type<T1>::type,
0501 typename is_polygon_type<T2>::type>::type, T1>::type &
0502 assign(T1& lvalue, const T2& rvalue) {
0503 polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue),
0504 polygon_traits<T2>::end_points(rvalue));
0505 return lvalue;
0506 }
0507
0508
0509 template <typename T1, typename T2>
0510 typename enable_if<
0511 typename gtl_and< typename is_mutable_polygon_with_holes_type<T1>::type,
0512 typename is_polygon_with_holes_type<T2>::type>::type, T1>::type &
0513 assign(T1& lvalue, const T2& rvalue) {
0514 polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue),
0515 polygon_traits<T2>::end_points(rvalue));
0516 polygon_with_holes_mutable_traits<T1>::set_holes(lvalue, polygon_with_holes_traits<T2>::begin_holes(rvalue),
0517 polygon_with_holes_traits<T2>::end_holes(rvalue));
0518 return lvalue;
0519 }
0520
0521
0522 template <typename T1, typename T2>
0523 typename enable_if< typename gtl_and< typename is_mutable_polygon_45_type<T1>::type, typename is_polygon_45_type<T2>::type>::type, T1>::type &
0524 assign(T1& lvalue, const T2& rvalue) {
0525 polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue),
0526 polygon_traits<T2>::end_points(rvalue));
0527 return lvalue;
0528 }
0529
0530
0531 template <typename T1, typename T2>
0532 typename enable_if<
0533 typename gtl_and< typename is_mutable_polygon_45_with_holes_type<T1>::type,
0534 typename is_polygon_45_with_holes_type<T2>::type>::type, T1>::type &
0535 assign(T1& lvalue, const T2& rvalue) {
0536 polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue),
0537 polygon_traits<T2>::end_points(rvalue));
0538 polygon_with_holes_mutable_traits<T1>::set_holes(lvalue, polygon_with_holes_traits<T2>::begin_holes(rvalue),
0539 polygon_with_holes_traits<T2>::end_holes(rvalue));
0540 return lvalue;
0541 }
0542
0543
0544 template <typename T1, typename T2>
0545 typename enable_if<
0546 typename gtl_and< typename is_mutable_polygon_90_type<T1>::type,
0547 typename is_polygon_90_type<T2>::type>::type, T1>::type &
0548 assign(T1& lvalue, const T2& rvalue) {
0549 polygon_90_mutable_traits<T1>::set_compact(lvalue, polygon_90_traits<T2>::begin_compact(rvalue),
0550 polygon_90_traits<T2>::end_compact(rvalue));
0551 return lvalue;
0552 }
0553
0554
0555 template <typename T1, typename T2>
0556 typename enable_if<
0557 typename gtl_and< typename is_mutable_polygon_90_with_holes_type<T1>::type,
0558 typename is_polygon_90_with_holes_type<T2>::type>::type, T1>::type &
0559 assign(T1& lvalue, const T2& rvalue) {
0560 polygon_90_mutable_traits<T1>::set_compact(lvalue, polygon_90_traits<T2>::begin_compact(rvalue),
0561 polygon_90_traits<T2>::end_compact(rvalue));
0562 polygon_with_holes_mutable_traits<T1>::set_holes(lvalue, polygon_with_holes_traits<T2>::begin_holes(rvalue),
0563 polygon_with_holes_traits<T2>::end_holes(rvalue));
0564 return lvalue;
0565 }
0566
0567
0568 template <typename T1, typename T2>
0569 typename enable_if<
0570 typename gtl_and< typename is_any_mutable_polygon_type<T1>::type,
0571 typename is_rectangle_concept<typename geometry_concept<T2>::type>::type>::type, T1>::type &
0572 assign(T1& polygon, const T2& rect) {
0573 typedef point_data<typename polygon_traits<T1>::coordinate_type> PT;
0574 PT points[4] = {PT(xl(rect), yl(rect)), PT(xh(rect), yl(rect)), PT(xh(rect), yh(rect)), PT(xl(rect), yh(rect))};
0575 set_points(polygon, points, points+4);
0576 return polygon;
0577 }
0578
0579
0580 template <typename polygon_type, typename point_type>
0581 typename enable_if< typename gtl_and< typename is_mutable_polygon_90_type<polygon_type>::type,
0582 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
0583 polygon_type>::type &
0584 convolve(polygon_type& polygon, const point_type& point) {
0585 std::vector<typename polygon_90_traits<polygon_type>::coordinate_type> coords;
0586 coords.reserve(::boost::polygon::size(polygon));
0587 bool pingpong = true;
0588 for(typename polygon_90_traits<polygon_type>::compact_iterator_type iter = begin_compact(polygon);
0589 iter != end_compact(polygon); ++iter) {
0590 coords.push_back((*iter) + (pingpong ? x(point) : y(point)));
0591 pingpong = !pingpong;
0592 }
0593 polygon_90_mutable_traits<polygon_type>::set_compact(polygon, coords.begin(), coords.end());
0594 return polygon;
0595 }
0596
0597
0598 template <typename polygon_type, typename point_type>
0599 typename enable_if< typename gtl_and< typename gtl_or<
0600 typename is_mutable_polygon_45_type<polygon_type>::type,
0601 typename is_mutable_polygon_type<polygon_type>::type>::type,
0602 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
0603 polygon_type>::type &
0604 convolve(polygon_type& polygon, const point_type& point) {
0605 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
0606 points.reserve(::boost::polygon::size(polygon));
0607 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
0608 iter != end_points(polygon); ++iter) {
0609 points.push_back(*iter);
0610 convolve(points.back(), point);
0611 }
0612 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
0613 return polygon;
0614 }
0615
0616
0617 template <typename polygon_type, typename point_type>
0618 typename enable_if<
0619 typename gtl_and< typename is_any_mutable_polygon_with_holes_type<polygon_type>::type,
0620 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
0621 polygon_type>::type &
0622 convolve(polygon_type& polygon, const point_type& point) {
0623 typedef typename polygon_with_holes_traits<polygon_type>::hole_type hole_type;
0624 hole_type h;
0625 set_points(h, begin_points(polygon), end_points(polygon));
0626 convolve(h, point);
0627 std::vector<hole_type> holes;
0628 holes.reserve(size_holes(polygon));
0629 for(typename polygon_with_holes_traits<polygon_type>::iterator_holes_type itr = begin_holes(polygon);
0630 itr != end_holes(polygon); ++itr) {
0631 holes.push_back(*itr);
0632 convolve(holes.back(), point);
0633 }
0634 assign(polygon, h);
0635 set_holes(polygon, holes.begin(), holes.end());
0636 return polygon;
0637 }
0638
0639
0640 template <typename T>
0641 typename enable_if< typename is_any_mutable_polygon_type<T>::type, T>::type &
0642 move(T& polygon, orientation_2d orient, typename polygon_traits<T>::coordinate_type displacement) {
0643 typedef typename polygon_traits<T>::coordinate_type Unit;
0644 if(orient == HORIZONTAL) return convolve(polygon, point_data<Unit>(displacement, Unit(0)));
0645 return convolve(polygon, point_data<Unit>(Unit(0), displacement));
0646 }
0647
0648
0649
0650
0651
0652
0653
0654 template <typename polygon_type, typename transform_type>
0655 typename enable_if< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, polygon_type>::type &
0656 transform(polygon_type& polygon, const transform_type& tr) {
0657 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
0658 points.reserve(::boost::polygon::size(polygon));
0659 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
0660 iter != end_points(polygon); ++iter) {
0661 points.push_back(*iter);
0662 transform(points.back(), tr);
0663 }
0664 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
0665 return polygon;
0666 }
0667
0668
0669 template <typename T, typename transform_type>
0670 typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type &
0671 transform(T& polygon, const transform_type& tr) {
0672 typedef typename polygon_with_holes_traits<T>::hole_type hole_type;
0673 hole_type h;
0674 set_points(h, begin_points(polygon), end_points(polygon));
0675 transform(h, tr);
0676 std::vector<hole_type> holes;
0677 holes.reserve(size_holes(polygon));
0678 for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon);
0679 itr != end_holes(polygon); ++itr) {
0680 holes.push_back(*itr);
0681 transform(holes.back(), tr);
0682 }
0683 assign(polygon, h);
0684 set_holes(polygon, holes.begin(), holes.end());
0685 return polygon;
0686 }
0687
0688 template <typename polygon_type>
0689 typename enable_if< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, polygon_type>::type &
0690 scale_up(polygon_type& polygon, typename coordinate_traits<typename polygon_traits<polygon_type>::coordinate_type>::unsigned_area_type factor) {
0691 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
0692 points.reserve(::boost::polygon::size(polygon));
0693 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
0694 iter != end_points(polygon); ++iter) {
0695 points.push_back(*iter);
0696 scale_up(points.back(), factor);
0697 }
0698 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
0699 return polygon;
0700 }
0701
0702 template <typename T>
0703 typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type &
0704 scale_up(T& polygon, typename coordinate_traits<typename polygon_traits<T>::coordinate_type>::unsigned_area_type factor) {
0705 typedef typename polygon_with_holes_traits<T>::hole_type hole_type;
0706 hole_type h;
0707 set_points(h, begin_points(polygon), end_points(polygon));
0708 scale_up(h, factor);
0709 std::vector<hole_type> holes;
0710 holes.reserve(size_holes(polygon));
0711 for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon);
0712 itr != end_holes(polygon); ++itr) {
0713 holes.push_back(*itr);
0714 scale_up(holes.back(), factor);
0715 }
0716 assign(polygon, h);
0717 set_holes(polygon, holes.begin(), holes.end());
0718 return polygon;
0719 }
0720
0721
0722 template <typename polygon_type>
0723 typename enable_if<
0724 typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type,
0725 typename gtl_not<typename gtl_same_type
0726 < forty_five_domain,
0727 typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type>::type,
0728 polygon_type>::type &
0729 scale_down(polygon_type& polygon, typename coordinate_traits<typename polygon_traits<polygon_type>::coordinate_type>::unsigned_area_type factor) {
0730 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
0731 points.reserve(::boost::polygon::size(polygon));
0732 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
0733 iter != end_points(polygon); ++iter) {
0734 points.push_back(*iter);
0735 scale_down(points.back(), factor);
0736 }
0737 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
0738 return polygon;
0739 }
0740
0741 template <typename Unit>
0742 Unit local_abs(Unit value) { return value < 0 ? (Unit)-value : value; }
0743
0744 template <typename Unit>
0745 void snap_point_vector_to_45(std::vector<point_data<Unit> >& pts) {
0746 typedef point_data<Unit> Point;
0747 if(pts.size() < 3) { pts.clear(); return; }
0748 typename std::vector<point_data<Unit> >::iterator endLocation = std::unique(pts.begin(), pts.end());
0749 if(endLocation != pts.end()){
0750 pts.resize(endLocation - pts.begin());
0751 }
0752 if(pts.back() == pts[0]) pts.pop_back();
0753
0754 int numPts = pts.size();
0755 bool wrap_around = false;
0756 for(int i = 0; i < numPts; ++i) {
0757 Point& pt1 = pts[i];
0758 Point& pt2 = pts[(i + 1) % numPts];
0759 Point& pt3 = pts[(i + 2) % numPts];
0760
0761 Unit deltax = x(pt2) - x(pt1);
0762 Unit deltay = y(pt2) - y(pt1);
0763 if(deltax && deltay &&
0764 local_abs(deltax) != local_abs(deltay)) {
0765
0766 Unit ndx = x(pt3) - x(pt2);
0767 Unit ndy = y(pt3) - y(pt2);
0768 if(ndx && ndy) {
0769 Unit diff = local_abs(local_abs(deltax) - local_abs(deltay));
0770 Unit halfdiff = diff/2;
0771 if((deltax > 0 && deltay > 0) ||
0772 (deltax < 0 && deltay < 0)) {
0773
0774 if(local_abs(deltax + halfdiff + (diff % 2)) ==
0775 local_abs(deltay - halfdiff)) {
0776 x(pt2, x(pt2) + halfdiff + (diff % 2));
0777 y(pt2, y(pt2) - halfdiff);
0778 } else if(local_abs(deltax - halfdiff - (diff % 2)) ==
0779 local_abs(deltay + halfdiff)) {
0780 x(pt2, x(pt2) - halfdiff - (diff % 2));
0781 y(pt2, y(pt2) + halfdiff);
0782 } else{
0783
0784 }
0785 } else {
0786
0787 if(local_abs(deltax + halfdiff + (diff % 2)) ==
0788 local_abs(deltay + halfdiff)) {
0789 x(pt2, x(pt2) + halfdiff + (diff % 2));
0790 y(pt2, y(pt2) + halfdiff);
0791 } else if(local_abs(deltax - halfdiff - (diff % 2)) ==
0792 local_abs(deltay - halfdiff)) {
0793 x(pt2, x(pt2) - halfdiff - (diff % 2));
0794 y(pt2, y(pt2) - halfdiff);
0795 } else {
0796
0797 }
0798 }
0799 if(i == numPts - 1 && (diff % 2)) {
0800
0801 if(!wrap_around) {
0802 wrap_around = true;
0803 i = -1;
0804 }
0805 }
0806 } else if(ndx) {
0807
0808
0809 Unit newDeltaX = local_abs(deltay);
0810 if(deltax < 0) newDeltaX *= -1;
0811 x(pt2, x(pt1) + newDeltaX);
0812 } else {
0813
0814
0815 Unit newDeltaY = local_abs(deltax);
0816 if(deltay < 0) newDeltaY *= -1;
0817 y(pt2, y(pt1) + newDeltaY);
0818 }
0819 }
0820 }
0821 }
0822
0823 template <typename polygon_type>
0824 typename enable_if< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, polygon_type>::type &
0825 snap_to_45(polygon_type& polygon) {
0826 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
0827 points.reserve(::boost::polygon::size(polygon));
0828 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
0829 iter != end_points(polygon); ++iter) {
0830 points.push_back(*iter);
0831 }
0832 snap_point_vector_to_45(points);
0833 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
0834 return polygon;
0835 }
0836
0837 template <typename polygon_type>
0838 typename enable_if< typename is_any_mutable_polygon_with_holes_type<polygon_type>::type, polygon_type>::type &
0839 snap_to_45(polygon_type& polygon) {
0840 typedef typename polygon_with_holes_traits<polygon_type>::hole_type hole_type;
0841 hole_type h;
0842 set_points(h, begin_points(polygon), end_points(polygon));
0843 snap_to_45(h);
0844 std::vector<hole_type> holes;
0845 holes.reserve(size_holes(polygon));
0846 for(typename polygon_with_holes_traits<polygon_type>::iterator_holes_type itr = begin_holes(polygon);
0847 itr != end_holes(polygon); ++itr) {
0848 holes.push_back(*itr);
0849 snap_to_45(holes.back());
0850 }
0851 assign(polygon, h);
0852 set_holes(polygon, holes.begin(), holes.end());
0853 return polygon;
0854 }
0855
0856
0857 template <typename polygon_type>
0858 typename enable_if<
0859 typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type,
0860 typename gtl_same_type
0861 < forty_five_domain,
0862 typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type,
0863 polygon_type>::type &
0864 scale_down(polygon_type& polygon, typename coordinate_traits<typename polygon_traits<polygon_type>::coordinate_type>::unsigned_area_type factor) {
0865 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
0866 points.reserve(::boost::polygon::size(polygon));
0867 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
0868 iter != end_points(polygon); ++iter) {
0869 points.push_back(*iter);
0870 scale_down(points.back(), factor);
0871 }
0872 snap_point_vector_to_45(points);
0873 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
0874 return polygon;
0875 }
0876
0877 template <typename T>
0878 typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type &
0879 scale_down(T& polygon, typename coordinate_traits<typename polygon_traits<T>::coordinate_type>::unsigned_area_type factor) {
0880 typedef typename polygon_with_holes_traits<T>::hole_type hole_type;
0881 hole_type h;
0882 set_points(h, begin_points(polygon), end_points(polygon));
0883 scale_down(h, factor);
0884 std::vector<hole_type> holes;
0885 holes.reserve(size_holes(polygon));
0886 for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon);
0887 itr != end_holes(polygon); ++itr) {
0888 holes.push_back(*itr);
0889 scale_down(holes.back(), factor);
0890 }
0891 assign(polygon, h);
0892 set_holes(polygon, holes.begin(), holes.end());
0893 return polygon;
0894 }
0895
0896
0897 template <typename polygon_type>
0898 typename enable_if<
0899 typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type,
0900 typename gtl_not<typename gtl_same_type
0901 < forty_five_domain,
0902 typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type>::type,
0903 polygon_type>::type &
0904 scale(polygon_type& polygon, double factor) {
0905 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
0906 points.reserve(::boost::polygon::size(polygon));
0907 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
0908 iter != end_points(polygon); ++iter) {
0909 points.push_back(*iter);
0910 scale(points.back(), anisotropic_scale_factor<double>(factor, factor));
0911 }
0912 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
0913 return polygon;
0914 }
0915
0916
0917 template <typename polygon_type>
0918 polygon_type&
0919 scale(polygon_type& polygon, double factor,
0920 typename enable_if<
0921 typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type,
0922 typename gtl_same_type
0923 < forty_five_domain,
0924 typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type>::type * = 0
0925 ) {
0926 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
0927 points.reserve(::boost::polygon::size(polygon));
0928 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
0929 iter != end_points(polygon); ++iter) {
0930 points.push_back(*iter);
0931 scale(points.back(), anisotropic_scale_factor<double>(factor, factor));
0932 }
0933 snap_point_vector_to_45(points);
0934 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
0935 return polygon;
0936 }
0937
0938 template <typename T>
0939 T&
0940 scale(T& polygon, double factor,
0941 typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type>::type * = 0
0942 ) {
0943 typedef typename polygon_with_holes_traits<T>::hole_type hole_type;
0944 hole_type h;
0945 set_points(h, begin_points(polygon), end_points(polygon));
0946 scale(h, factor);
0947 std::vector<hole_type> holes;
0948 holes.reserve(size_holes(polygon));
0949 for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon);
0950 itr != end_holes(polygon); ++itr) {
0951 holes.push_back(*itr);
0952 scale(holes.back(), factor);
0953 }
0954 assign(polygon, h);
0955 set_holes(polygon, holes.begin(), holes.end());
0956 return polygon;
0957 }
0958
0959 template <typename iterator_type, typename area_type>
0960 static area_type
0961 point_sequence_area(iterator_type begin_range, iterator_type end_range) {
0962 typedef typename std::iterator_traits<iterator_type>::value_type point_type;
0963 if(begin_range == end_range) return area_type(0);
0964 point_type first = *begin_range;
0965 point_type previous = first;
0966 ++begin_range;
0967
0968 area_type y_base = (area_type)y(first);
0969
0970
0971 area_type area(0);
0972 while (begin_range != end_range) {
0973 area_type x1 = (area_type)x(previous);
0974 area_type x2 = (area_type)x(*begin_range);
0975 #ifdef BOOST_POLYGON_ICC
0976 #pragma warning (push)
0977 #pragma warning (disable:1572)
0978 #endif
0979 if(x1 != x2) {
0980 #ifdef BOOST_POLYGON_ICC
0981 #pragma warning (pop)
0982 #endif
0983
0984 area += (x2 - x1) * (((area_type)y(*begin_range) - y_base) +
0985 ((area_type)y(previous) - y_base)) / 2;
0986 }
0987 previous = *begin_range;
0988
0989 ++begin_range;
0990 }
0991
0992 if(!equivalence(first, previous)) {
0993 area_type x1 = (area_type)x(previous);
0994 area_type x2 = (area_type)x(first);
0995 area += (x2 - x1) * (((area_type)y(first) - y_base) +
0996 ((area_type)y(previous) - y_base)) / 2;
0997 }
0998 return area;
0999 }
1000
1001 template <typename T>
1002 typename enable_if<
1003 typename is_polygon_with_holes_type<T>::type,
1004 typename area_type_by_domain< typename geometry_domain<typename geometry_concept<T>::type>::type,
1005 typename polygon_traits<T>::coordinate_type>::type>::type
1006 area(const T& polygon) {
1007 typedef typename area_type_by_domain< typename geometry_domain<typename geometry_concept<T>::type>::type,
1008 typename polygon_traits<T>::coordinate_type>::type area_type;
1009 area_type retval = point_sequence_area<typename polygon_traits<T>::iterator_type, area_type>
1010 (begin_points(polygon), end_points(polygon));
1011 if(retval < 0) retval *= -1;
1012 for(typename polygon_with_holes_traits<T>::iterator_holes_type itr =
1013 polygon_with_holes_traits<T>::begin_holes(polygon);
1014 itr != polygon_with_holes_traits<T>::end_holes(polygon); ++itr) {
1015 area_type tmp_area = point_sequence_area
1016 <typename polygon_traits<typename polygon_with_holes_traits<T>::hole_type>::iterator_type, area_type>
1017 (begin_points(*itr), end_points(*itr));
1018 if(tmp_area < 0) tmp_area *= -1;
1019 retval -= tmp_area;
1020 }
1021 return retval;
1022 }
1023
1024 template <typename iT>
1025 bool point_sequence_is_45(iT itr, iT itr_end) {
1026 typedef typename std::iterator_traits<iT>::value_type Point;
1027 typedef typename point_traits<Point>::coordinate_type Unit;
1028 if(itr == itr_end) return true;
1029 Point firstPt = *itr;
1030 Point prevPt = firstPt;
1031 ++itr;
1032 while(itr != itr_end) {
1033 Point pt = *itr;
1034 Unit deltax = x(pt) - x(prevPt);
1035 Unit deltay = y(pt) - y(prevPt);
1036 if(deltax && deltay &&
1037 local_abs(deltax) != local_abs(deltay))
1038 return false;
1039 prevPt = pt;
1040 ++itr;
1041 }
1042 Unit deltax = x(firstPt) - x(prevPt);
1043 Unit deltay = y(firstPt) - y(prevPt);
1044 if(deltax && deltay &&
1045 local_abs(deltax) != local_abs(deltay))
1046 return false;
1047 return true;
1048 }
1049
1050 template <typename polygon_type>
1051 typename enable_if< typename is_polygon_with_holes_type<polygon_type>::type, bool>::type
1052 is_45(const polygon_type& polygon) {
1053 typename polygon_traits<polygon_type>::iterator_type itr = begin_points(polygon), itr_end = end_points(polygon);
1054 if(!point_sequence_is_45(itr, itr_end)) return false;
1055 typename polygon_with_holes_traits<polygon_type>::iterator_holes_type itrh = begin_holes(polygon), itrh_end = end_holes(polygon);
1056 typedef typename polygon_with_holes_traits<polygon_type>::hole_type hole_type;
1057 for(; itrh != itrh_end; ++ itrh) {
1058 typename polygon_traits<hole_type>::iterator_type itr1 = begin_points(polygon), itr1_end = end_points(polygon);
1059 if(!point_sequence_is_45(itr1, itr1_end)) return false;
1060 }
1061 return true;
1062 }
1063
1064 template <typename distance_type, typename iterator_type>
1065 distance_type point_sequence_distance(iterator_type itr, iterator_type itr_end) {
1066 typedef distance_type Unit;
1067 typedef iterator_type iterator;
1068 typedef typename std::iterator_traits<iterator>::value_type point_type;
1069 Unit return_value = Unit(0);
1070 point_type previous_point, first_point;
1071 if(itr == itr_end) return return_value;
1072 previous_point = first_point = *itr;
1073 ++itr;
1074 for( ; itr != itr_end; ++itr) {
1075 point_type current_point = *itr;
1076 return_value += (Unit)euclidean_distance(current_point, previous_point);
1077 previous_point = current_point;
1078 }
1079 return_value += (Unit)euclidean_distance(previous_point, first_point);
1080 return return_value;
1081 }
1082
1083 template <typename T>
1084 typename distance_type_by_domain
1085 <typename geometry_domain<typename geometry_concept<T>::type>::type, typename polygon_traits<T>::coordinate_type>::type
1086 perimeter(const T& polygon,
1087 typename enable_if<
1088 typename is_polygon_with_holes_type<T>::type>::type * = 0
1089 ) {
1090 typedef typename distance_type_by_domain
1091 <typename geometry_domain<typename geometry_concept<T>::type>::type, typename polygon_traits<T>::coordinate_type>::type Unit;
1092 typedef typename polygon_traits<T>::iterator_type iterator;
1093 iterator itr = begin_points(polygon);
1094 iterator itr_end = end_points(polygon);
1095 Unit return_value = point_sequence_distance<Unit, iterator>(itr, itr_end);
1096 for(typename polygon_with_holes_traits<T>::iterator_holes_type itr_holes = begin_holes(polygon);
1097 itr_holes != end_holes(polygon); ++itr_holes) {
1098 typedef typename polygon_traits<typename polygon_with_holes_traits<T>::hole_type>::iterator_type hitertype;
1099 return_value += point_sequence_distance<Unit, hitertype>(begin_points(*itr_holes), end_points(*itr_holes));
1100 }
1101 return return_value;
1102 }
1103
1104 template <typename T>
1105 typename enable_if <typename is_polygon_with_holes_type<T>::type,
1106 direction_1d>::type
1107 winding(const T& polygon) {
1108 winding_direction wd = polygon_traits<T>::winding(polygon);
1109 if(wd != unknown_winding) {
1110 return wd == clockwise_winding ? CLOCKWISE: COUNTERCLOCKWISE;
1111 }
1112 typedef typename area_type_by_domain< typename geometry_domain<typename geometry_concept<T>::type>::type,
1113 typename polygon_traits<T>::coordinate_type>::type area_type;
1114 return point_sequence_area<typename polygon_traits<T>::iterator_type, area_type>(begin_points(polygon), end_points(polygon)) < 0 ?
1115 COUNTERCLOCKWISE : CLOCKWISE;
1116 }
1117
1118 template <typename T, typename input_point_type>
1119 typename enable_if<
1120 typename gtl_and<
1121 typename is_polygon_90_type<T>::type,
1122 typename gtl_same_type<
1123 typename geometry_concept<input_point_type>::type,
1124 point_concept
1125 >::type
1126 >::type,
1127 bool
1128 >::type contains(
1129 const T& polygon,
1130 const input_point_type& point,
1131 bool consider_touch = true) {
1132 typedef T polygon_type;
1133 typedef typename polygon_traits<polygon_type>::coordinate_type coordinate_type;
1134 typedef typename polygon_traits<polygon_type>::iterator_type iterator;
1135 typedef typename std::iterator_traits<iterator>::value_type point_type;
1136 coordinate_type point_x = x(point);
1137 coordinate_type point_y = y(point);
1138
1139
1140
1141
1142
1143
1144
1145 int num_full_intersections = 0;
1146 int num_half_intersections = 0;
1147 for (iterator iter = begin_points(polygon); iter != end_points(polygon);) {
1148 point_type curr_point = *iter;
1149 ++iter;
1150 point_type next_point = (iter == end_points(polygon)) ? *begin_points(polygon) : *iter;
1151 if (x(curr_point) == x(next_point)) {
1152 if (x(curr_point) > point_x) {
1153 continue;
1154 }
1155 coordinate_type min_y = (std::min)(y(curr_point), y(next_point));
1156 coordinate_type max_y = (std::max)(y(curr_point), y(next_point));
1157 if (point_y > min_y && point_y < max_y) {
1158 if (x(curr_point) == point_x) {
1159 return consider_touch;
1160 }
1161 ++num_full_intersections;
1162 }
1163 if (point_y == min_y || point_y == max_y) {
1164 num_half_intersections += (y(curr_point) < y(next_point) ? 1 : -1);
1165 }
1166 } else {
1167 coordinate_type min_x = (std::min)(x(curr_point), x(next_point));
1168 coordinate_type max_x = (std::max)(x(curr_point), x(next_point));
1169 if (point_x >= min_x && point_x <= max_x) {
1170 if (y(curr_point) == point_y) {
1171 return consider_touch;
1172 }
1173 }
1174 }
1175 }
1176 int total_intersections = num_full_intersections + (num_half_intersections >> 1);
1177 return total_intersections & 1;
1178 }
1179
1180
1181 template <typename Unit>
1182 struct edge_utils {
1183 typedef point_data<Unit> Point;
1184 typedef std::pair<Point, Point> half_edge;
1185
1186 class less_point {
1187 public:
1188 typedef Point first_argument_type;
1189 typedef Point second_argument_type;
1190 typedef bool result_type;
1191 inline less_point() {}
1192 inline bool operator () (const Point& pt1, const Point& pt2) const {
1193 if(pt1.get(HORIZONTAL) < pt2.get(HORIZONTAL)) return true;
1194 if(pt1.get(HORIZONTAL) == pt2.get(HORIZONTAL)) {
1195 if(pt1.get(VERTICAL) < pt2.get(VERTICAL)) return true;
1196 }
1197 return false;
1198 }
1199 };
1200
1201 static inline bool between(Point pt, Point pt1, Point pt2) {
1202 less_point lp;
1203 if(lp(pt1, pt2))
1204 return lp(pt, pt2) && lp(pt1, pt);
1205 return lp(pt, pt1) && lp(pt2, pt);
1206 }
1207
1208 template <typename area_type>
1209 static inline bool equal_slope(area_type dx1, area_type dy1, area_type dx2, area_type dy2) {
1210 typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type;
1211 unsigned_product_type cross_1 = (unsigned_product_type)(dx2 < 0 ? -dx2 :dx2) * (unsigned_product_type)(dy1 < 0 ? -dy1 : dy1);
1212 unsigned_product_type cross_2 = (unsigned_product_type)(dx1 < 0 ? -dx1 :dx1) * (unsigned_product_type)(dy2 < 0 ? -dy2 : dy2);
1213 int dx1_sign = dx1 < 0 ? -1 : 1;
1214 int dx2_sign = dx2 < 0 ? -1 : 1;
1215 int dy1_sign = dy1 < 0 ? -1 : 1;
1216 int dy2_sign = dy2 < 0 ? -1 : 1;
1217 int cross_1_sign = dx2_sign * dy1_sign;
1218 int cross_2_sign = dx1_sign * dy2_sign;
1219 return cross_1 == cross_2 && (cross_1_sign == cross_2_sign || cross_1 == 0);
1220 }
1221
1222 static inline bool equal_slope(const Unit& x, const Unit& y,
1223 const Point& pt1, const Point& pt2) {
1224 const Point* pts[2] = {&pt1, &pt2};
1225 typedef typename coordinate_traits<Unit>::manhattan_area_type at;
1226 at dy2 = (at)pts[1]->get(VERTICAL) - (at)y;
1227 at dy1 = (at)pts[0]->get(VERTICAL) - (at)y;
1228 at dx2 = (at)pts[1]->get(HORIZONTAL) - (at)x;
1229 at dx1 = (at)pts[0]->get(HORIZONTAL) - (at)x;
1230 return equal_slope(dx1, dy1, dx2, dy2);
1231 }
1232
1233 template <typename area_type>
1234 static inline bool less_slope(area_type dx1, area_type dy1, area_type dx2, area_type dy2) {
1235
1236 if(dx1 < 0) {
1237 dy1 *= -1;
1238 dx1 *= -1;
1239 } else if(dx1 == 0) {
1240
1241 return false;
1242 }
1243 if(dx2 < 0) {
1244 dy2 *= -1;
1245 dx2 *= -1;
1246 } else if(dx2 == 0) {
1247
1248 return dx1 != 0;
1249 }
1250 typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type;
1251 unsigned_product_type cross_1 = (unsigned_product_type)(dx2 < 0 ? -dx2 :dx2) * (unsigned_product_type)(dy1 < 0 ? -dy1 : dy1);
1252 unsigned_product_type cross_2 = (unsigned_product_type)(dx1 < 0 ? -dx1 :dx1) * (unsigned_product_type)(dy2 < 0 ? -dy2 : dy2);
1253 int dx1_sign = dx1 < 0 ? -1 : 1;
1254 int dx2_sign = dx2 < 0 ? -1 : 1;
1255 int dy1_sign = dy1 < 0 ? -1 : 1;
1256 int dy2_sign = dy2 < 0 ? -1 : 1;
1257 int cross_1_sign = dx2_sign * dy1_sign;
1258 int cross_2_sign = dx1_sign * dy2_sign;
1259 if(cross_1_sign < cross_2_sign) return true;
1260 if(cross_2_sign < cross_1_sign) return false;
1261 if(cross_1_sign == -1) return cross_2 < cross_1;
1262 return cross_1 < cross_2;
1263 }
1264
1265 static inline bool less_slope(const Unit& x, const Unit& y,
1266 const Point& pt1, const Point& pt2) {
1267 const Point* pts[2] = {&pt1, &pt2};
1268
1269 typedef typename coordinate_traits<Unit>::manhattan_area_type at;
1270 at dy2 = (at)pts[1]->get(VERTICAL) - (at)y;
1271 at dy1 = (at)pts[0]->get(VERTICAL) - (at)y;
1272 at dx2 = (at)pts[1]->get(HORIZONTAL) - (at)x;
1273 at dx1 = (at)pts[0]->get(HORIZONTAL) - (at)x;
1274 return less_slope(dx1, dy1, dx2, dy2);
1275 }
1276
1277
1278
1279 static inline int on_above_or_below(Point pt, const half_edge& he) {
1280 if(pt == he.first || pt == he.second) return 0;
1281 if(equal_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), he.first, he.second)) return 0;
1282 bool less_result = less_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), he.first, he.second);
1283 int retval = less_result ? -1 : 1;
1284 less_point lp;
1285 if(lp(he.second, he.first)) retval *= -1;
1286 if(!between(pt, he.first, he.second)) retval *= -1;
1287 return retval;
1288 }
1289 };
1290
1291 template <typename T, typename input_point_type>
1292 typename enable_if<
1293 typename gtl_and< typename is_any_mutable_polygon_with_holes_type<T>::type,
1294 typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type,
1295 bool>::type
1296 contains(const T& polygon, const input_point_type& point, bool consider_touch = true) {
1297 typedef typename polygon_with_holes_traits<T>::iterator_holes_type holes_iterator;
1298 bool isInside = contains( view_as< typename polygon_from_polygon_with_holes_type<
1299 typename geometry_concept<T>::type>::type>( polygon ), point, consider_touch );
1300 if(!isInside) return false;
1301 holes_iterator itH = begin_holes( polygon );
1302 while( itH != end_holes( polygon ) ) {
1303 if( contains( *itH, point, !consider_touch ) ) {
1304 isInside = false;
1305 break;
1306 }
1307 ++itH;
1308 }
1309 return isInside;
1310 }
1311
1312 template <typename T, typename input_point_type>
1313 typename enable_if<
1314 typename gtl_and_3<
1315 typename is_polygon_type<T>::type,
1316 typename gtl_different_type<typename geometry_domain<typename geometry_concept<T>::type>::type, manhattan_domain>::type,
1317 typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type,
1318 bool>::type
1319 contains(const T& polygon, const input_point_type& point, bool consider_touch = true) {
1320 typedef typename point_traits<input_point_type>::coordinate_type Unit;
1321 typedef point_data<Unit> Point;
1322 typedef std::pair<Point, Point> half_edge;
1323 typedef typename polygon_traits<T>::iterator_type iterator;
1324 iterator itr = begin_points(polygon);
1325 iterator itrEnd = end_points(polygon);
1326 half_edge he;
1327 if(itr == itrEnd) return false;
1328 assign(he.first, *itr);
1329 Point firstPt;
1330 assign(firstPt, *itr);
1331 ++itr;
1332 if(itr == itrEnd) return false;
1333 bool done = false;
1334 int above = 0;
1335 while(!done) {
1336 Point currentPt;
1337 if(itr == itrEnd) {
1338 done = true;
1339 currentPt = firstPt;
1340 } else {
1341 assign(currentPt, *itr);
1342 ++itr;
1343 }
1344 if(currentPt == he.first) {
1345 continue;
1346 } else {
1347 he.second = currentPt;
1348 if(equivalence(point, currentPt)) return consider_touch;
1349 Unit xmin = (std::min)(x(he.first), x(he.second));
1350 Unit xmax = (std::max)(x(he.first), x(he.second));
1351 if(x(point) >= xmin && x(point) < xmax) {
1352 Point tmppt;
1353 assign(tmppt, point);
1354 int oabedge = edge_utils<Unit>::on_above_or_below(tmppt, he);
1355 if(oabedge == 0) return consider_touch;
1356 if(oabedge == 1) ++above;
1357 } else if(x(point) == xmax) {
1358 if(x(point) == xmin) {
1359 Unit ymin = (std::min)(y(he.first), y(he.second));
1360 Unit ymax = (std::max)(y(he.first), y(he.second));
1361 Unit ypt = y(point);
1362 if(ypt <= ymax && ypt >= ymin)
1363 return consider_touch;
1364 } else {
1365 Point tmppt;
1366 assign(tmppt, point);
1367 if( edge_utils<Unit>::on_above_or_below(tmppt, he) == 0 ) {
1368 return consider_touch;
1369 }
1370 }
1371 }
1372 }
1373 he.first = he.second;
1374 }
1375 return above % 2 != 0;
1376 }
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432 template <typename T1, typename T2>
1433 typename enable_if<
1434 typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<T1>::type>::type,
1435 typename is_polygon_with_holes_type<T2>::type>::type,
1436 bool>::type
1437 extents(T1& bounding_box, const T2& polygon) {
1438 typedef typename polygon_traits<T2>::iterator_type iterator;
1439 bool first_iteration = true;
1440 iterator itr_end = end_points(polygon);
1441 for(iterator itr = begin_points(polygon); itr != itr_end; ++itr) {
1442 if(first_iteration) {
1443 set_points(bounding_box, *itr, *itr);
1444 first_iteration = false;
1445 } else {
1446 encompass(bounding_box, *itr);
1447 }
1448 }
1449 if(first_iteration) return false;
1450 return true;
1451 }
1452
1453 template <typename T1, typename T2>
1454 typename enable_if<
1455 typename gtl_and< typename is_mutable_point_concept<typename geometry_concept<T1>::type>::type,
1456 typename is_polygon_with_holes_type<T2>::type>::type,
1457 bool>::type
1458 center(T1& center_point, const T2& polygon) {
1459 typedef typename polygon_traits<T2>::coordinate_type coordinate_type;
1460 rectangle_data<coordinate_type> bbox;
1461 extents(bbox, polygon);
1462 return center(center_point, bbox);
1463 }
1464
1465 template <class T>
1466 template <class T2>
1467 polygon_90_data<T>& polygon_90_data<T>::operator=(const T2& rvalue) {
1468 assign(*this, rvalue);
1469 return *this;
1470 }
1471
1472 template <class T>
1473 template <class T2>
1474 polygon_45_data<T>& polygon_45_data<T>::operator=(const T2& rvalue) {
1475 assign(*this, rvalue);
1476 return *this;
1477 }
1478
1479 template <class T>
1480 template <class T2>
1481 polygon_data<T>& polygon_data<T>::operator=(const T2& rvalue) {
1482 assign(*this, rvalue);
1483 return *this;
1484 }
1485
1486 template <class T>
1487 template <class T2>
1488 polygon_90_with_holes_data<T>& polygon_90_with_holes_data<T>::operator=(const T2& rvalue) {
1489 assign(*this, rvalue);
1490 return *this;
1491 }
1492
1493 template <class T>
1494 template <class T2>
1495 polygon_45_with_holes_data<T>& polygon_45_with_holes_data<T>::operator=(const T2& rvalue) {
1496 assign(*this, rvalue);
1497 return *this;
1498 }
1499
1500 template <class T>
1501 template <class T2>
1502 polygon_with_holes_data<T>& polygon_with_holes_data<T>::operator=(const T2& rvalue) {
1503 assign(*this, rvalue);
1504 return *this;
1505 }
1506
1507 template <typename T>
1508 struct geometry_concept<polygon_data<T> > {
1509 typedef polygon_concept type;
1510 };
1511 template <typename T>
1512 struct geometry_concept<polygon_45_data<T> > {
1513 typedef polygon_45_concept type;
1514 };
1515 template <typename T>
1516 struct geometry_concept<polygon_90_data<T> > {
1517 typedef polygon_90_concept type;
1518 };
1519 template <typename T>
1520 struct geometry_concept<polygon_with_holes_data<T> > {
1521 typedef polygon_with_holes_concept type;
1522 };
1523 template <typename T>
1524 struct geometry_concept<polygon_45_with_holes_data<T> > {
1525 typedef polygon_45_with_holes_concept type;
1526 };
1527 template <typename T>
1528 struct geometry_concept<polygon_90_with_holes_data<T> > {
1529 typedef polygon_90_with_holes_concept type;
1530 };
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553 template <typename T> struct get_void {};
1554 template <> struct get_void<gtl_yes> { typedef void type; };
1555
1556 template <typename T> struct polygon_with_holes_traits<
1557 T, typename get_void<typename is_any_mutable_polygon_without_holes_type<T>::type>::type > {
1558 typedef T hole_type;
1559 typedef const hole_type* iterator_holes_type;
1560 static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; }
1561 static inline iterator_holes_type end_holes(const hole_type& t) { return &t; }
1562 };
1563
1564 template <typename T>
1565 struct view_of<rectangle_concept, T> {
1566 typedef typename polygon_traits<T>::coordinate_type coordinate_type;
1567 typedef interval_data<coordinate_type> interval_type;
1568 rectangle_data<coordinate_type> rect;
1569 view_of(const T& obj) : rect() {
1570 point_data<coordinate_type> pts[2];
1571 typename polygon_traits<T>::iterator_type itr =
1572 begin_points(obj), itre = end_points(obj);
1573 if(itr == itre) return;
1574 assign(pts[0], *itr);
1575 ++itr;
1576 if(itr == itre) return;
1577 ++itr;
1578 if(itr == itre) return;
1579 assign(pts[1], *itr);
1580 set_points(rect, pts[0], pts[1]);
1581 }
1582 inline interval_type get(orientation_2d orient) const {
1583 return rect.get(orient); }
1584 };
1585
1586 template <typename T>
1587 struct geometry_concept<view_of<rectangle_concept, T> > {
1588 typedef rectangle_concept type;
1589 };
1590
1591 template <typename T>
1592 struct view_of<polygon_45_concept, T> {
1593 const T* t;
1594 view_of(const T& obj) : t(&obj) {}
1595 typedef typename polygon_traits<T>::coordinate_type coordinate_type;
1596 typedef typename polygon_traits<T>::iterator_type iterator_type;
1597 typedef typename polygon_traits<T>::point_type point_type;
1598
1599
1600 inline iterator_type begin() const {
1601 return polygon_traits<T>::begin_points(*t);
1602 }
1603
1604
1605 inline iterator_type end() const {
1606 return polygon_traits<T>::end_points(*t);
1607 }
1608
1609
1610 inline std::size_t size() const {
1611 return polygon_traits<T>::size(*t);
1612 }
1613
1614
1615 inline winding_direction winding() const {
1616 return polygon_traits<T>::winding(*t);
1617 }
1618 };
1619
1620 template <typename T>
1621 struct geometry_concept<view_of<polygon_45_concept, T> > {
1622 typedef polygon_45_concept type;
1623 };
1624
1625 template <typename T>
1626 struct view_of<polygon_90_concept, T> {
1627 const T* t;
1628 view_of(const T& obj) : t(&obj) {}
1629 typedef typename polygon_traits<T>::coordinate_type coordinate_type;
1630 typedef typename polygon_traits<T>::iterator_type iterator_type;
1631 typedef typename polygon_traits<T>::point_type point_type;
1632 typedef iterator_points_to_compact<iterator_type, point_type> compact_iterator_type;
1633
1634
1635 inline compact_iterator_type begin_compact() const {
1636 return compact_iterator_type(polygon_traits<T>::begin_points(*t),
1637 polygon_traits<T>::end_points(*t));
1638 }
1639
1640
1641 inline compact_iterator_type end_compact() const {
1642 return compact_iterator_type(polygon_traits<T>::end_points(*t),
1643 polygon_traits<T>::end_points(*t));
1644 }
1645
1646
1647 inline std::size_t size() const {
1648 return polygon_traits<T>::size(*t);
1649 }
1650
1651
1652 inline winding_direction winding() const {
1653 return polygon_traits<T>::winding(*t);
1654 }
1655 };
1656
1657 template <typename T>
1658 struct geometry_concept<view_of<polygon_90_concept, T> > {
1659 typedef polygon_90_concept type;
1660 };
1661
1662 template <typename T>
1663 struct view_of<polygon_45_with_holes_concept, T> {
1664 const T* t;
1665 view_of(const T& obj) : t(&obj) {}
1666 typedef typename polygon_traits<T>::coordinate_type coordinate_type;
1667 typedef typename polygon_traits<T>::iterator_type iterator_type;
1668 typedef typename polygon_traits<T>::point_type point_type;
1669 typedef view_of<polygon_45_concept, typename polygon_with_holes_traits<T>::hole_type> hole_type;
1670 struct iterator_holes_type {
1671 typedef std::forward_iterator_tag iterator_category;
1672 typedef hole_type value_type;
1673 typedef std::ptrdiff_t difference_type;
1674 typedef const hole_type* pointer;
1675 typedef const hole_type& reference;
1676 typedef typename polygon_with_holes_traits<T>::iterator_holes_type iht;
1677 iht internal_itr;
1678 iterator_holes_type() : internal_itr() {}
1679 iterator_holes_type(iht iht_in) : internal_itr(iht_in) {}
1680 inline iterator_holes_type& operator++() {
1681 ++internal_itr;
1682 return *this;
1683 }
1684 inline const iterator_holes_type operator++(int) {
1685 iterator_holes_type tmp(*this);
1686 ++(*this);
1687 return tmp;
1688 }
1689 inline bool operator==(const iterator_holes_type& that) const {
1690 return (internal_itr == that.internal_itr);
1691 }
1692 inline bool operator!=(const iterator_holes_type& that) const {
1693 return (internal_itr != that.internal_itr);
1694 }
1695 inline value_type operator*() const {
1696 return view_as<polygon_45_concept>(*internal_itr);
1697 }
1698 };
1699
1700
1701 inline iterator_type begin() const {
1702 return polygon_traits<T>::begin_points(*t);
1703 }
1704
1705
1706 inline iterator_type end() const {
1707 return polygon_traits<T>::end_points(*t);
1708 }
1709
1710
1711 inline std::size_t size() const {
1712 return polygon_traits<T>::size(*t);
1713 }
1714
1715
1716 inline winding_direction winding() const {
1717 return polygon_traits<T>::winding(*t);
1718 }
1719
1720
1721 inline iterator_holes_type begin_holes() const {
1722 return polygon_with_holes_traits<T>::begin_holes(*t);
1723 }
1724
1725
1726 inline iterator_holes_type end_holes() const {
1727 return polygon_with_holes_traits<T>::end_holes(*t);
1728 }
1729
1730
1731 inline std::size_t size_holes() const {
1732 return polygon_with_holes_traits<T>::size_holes(*t);
1733 }
1734
1735 };
1736
1737 template <typename T>
1738 struct geometry_concept<view_of<polygon_45_with_holes_concept, T> > {
1739 typedef polygon_45_with_holes_concept type;
1740 };
1741
1742 template <typename T>
1743 struct view_of<polygon_90_with_holes_concept, T> {
1744 const T* t;
1745 view_of(const T& obj) : t(&obj) {}
1746 typedef typename polygon_traits<T>::coordinate_type coordinate_type;
1747 typedef typename polygon_traits<T>::iterator_type iterator_type;
1748 typedef typename polygon_traits<T>::point_type point_type;
1749 typedef iterator_points_to_compact<iterator_type, point_type> compact_iterator_type;
1750 typedef view_of<polygon_90_concept, typename polygon_with_holes_traits<T>::hole_type> hole_type;
1751 struct iterator_holes_type {
1752 typedef std::forward_iterator_tag iterator_category;
1753 typedef hole_type value_type;
1754 typedef std::ptrdiff_t difference_type;
1755 typedef const hole_type* pointer;
1756 typedef const hole_type& reference;
1757 typedef typename polygon_with_holes_traits<T>::iterator_holes_type iht;
1758 iht internal_itr;
1759 iterator_holes_type() : internal_itr() {}
1760 iterator_holes_type(iht iht_in) : internal_itr(iht_in) {}
1761 inline iterator_holes_type& operator++() {
1762 ++internal_itr;
1763 return *this;
1764 }
1765 inline const iterator_holes_type operator++(int) {
1766 iterator_holes_type tmp(*this);
1767 ++(*this);
1768 return tmp;
1769 }
1770 inline bool operator==(const iterator_holes_type& that) const {
1771 return (internal_itr == that.internal_itr);
1772 }
1773 inline bool operator!=(const iterator_holes_type& that) const {
1774 return (internal_itr != that.internal_itr);
1775 }
1776 inline value_type operator*() const {
1777 return view_as<polygon_90_concept>(*internal_itr);
1778 }
1779 };
1780
1781
1782 inline compact_iterator_type begin_compact() const {
1783 return compact_iterator_type(polygon_traits<T>::begin_points(*t),
1784 polygon_traits<T>::end_points(*t));
1785 }
1786
1787
1788 inline compact_iterator_type end_compact() const {
1789 return compact_iterator_type(polygon_traits<T>::end_points(*t),
1790 polygon_traits<T>::end_points(*t));
1791 }
1792
1793
1794 inline std::size_t size() const {
1795 return polygon_traits<T>::size(*t);
1796 }
1797
1798
1799 inline winding_direction winding() const {
1800 return polygon_traits<T>::winding(*t);
1801 }
1802
1803
1804 inline iterator_holes_type begin_holes() const {
1805 return polygon_with_holes_traits<T>::begin_holes(*t);
1806 }
1807
1808
1809 inline iterator_holes_type end_holes() const {
1810 return polygon_with_holes_traits<T>::end_holes(*t);
1811 }
1812
1813
1814 inline std::size_t size_holes() const {
1815 return polygon_with_holes_traits<T>::size_holes(*t);
1816 }
1817
1818 };
1819
1820 template <typename T>
1821 struct geometry_concept<view_of<polygon_90_with_holes_concept, T> > {
1822 typedef polygon_90_with_holes_concept type;
1823 };
1824
1825 template <typename T>
1826 struct view_of<polygon_concept, T> {
1827 const T* t;
1828 view_of(const T& obj) : t(&obj) {}
1829 typedef typename polygon_traits<T>::coordinate_type coordinate_type;
1830 typedef typename polygon_traits<T>::iterator_type iterator_type;
1831 typedef typename polygon_traits<T>::point_type point_type;
1832
1833
1834 inline iterator_type begin() const {
1835 return polygon_traits<T>::begin_points(*t);
1836 }
1837
1838
1839 inline iterator_type end() const {
1840 return polygon_traits<T>::end_points(*t);
1841 }
1842
1843
1844 inline std::size_t size() const {
1845 return polygon_traits<T>::size(*t);
1846 }
1847
1848
1849 inline winding_direction winding() const {
1850 return polygon_traits<T>::winding(*t);
1851 }
1852 };
1853
1854 template <typename T>
1855 struct geometry_concept<view_of<polygon_concept, T> > {
1856 typedef polygon_concept type;
1857 };
1858 }
1859 }
1860
1861 #endif