annotate DEPENDENCIES/generic/include/boost/polygon/polygon_traits.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /*
Chris@16 2 Copyright 2008 Intel Corporation
Chris@16 3
Chris@16 4 Use, modification and distribution are subject to the Boost Software License,
Chris@16 5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 http://www.boost.org/LICENSE_1_0.txt).
Chris@16 7 */
Chris@16 8 #ifndef BOOST_POLYGON_POLYGON_TRAITS_HPP
Chris@16 9 #define BOOST_POLYGON_POLYGON_TRAITS_HPP
Chris@16 10 namespace boost { namespace polygon{
Chris@16 11
Chris@16 12 template <typename T, typename enable = gtl_yes>
Chris@16 13 struct polygon_90_traits {
Chris@16 14 typedef typename T::coordinate_type coordinate_type;
Chris@16 15 typedef typename T::compact_iterator_type compact_iterator_type;
Chris@16 16
Chris@16 17 // Get the begin iterator
Chris@16 18 static inline compact_iterator_type begin_compact(const T& t) {
Chris@16 19 return t.begin_compact();
Chris@16 20 }
Chris@16 21
Chris@16 22 // Get the end iterator
Chris@16 23 static inline compact_iterator_type end_compact(const T& t) {
Chris@16 24 return t.end_compact();
Chris@16 25 }
Chris@16 26
Chris@16 27 // Get the number of sides of the polygon
Chris@16 28 static inline std::size_t size(const T& t) {
Chris@16 29 return t.size();
Chris@16 30 }
Chris@16 31
Chris@16 32 // Get the winding direction of the polygon
Chris@16 33 static inline winding_direction winding(const T&) {
Chris@16 34 return unknown_winding;
Chris@16 35 }
Chris@16 36 };
Chris@16 37
Chris@16 38 template <typename T>
Chris@16 39 struct polygon_traits_general {
Chris@16 40 typedef typename T::coordinate_type coordinate_type;
Chris@16 41 typedef typename T::iterator_type iterator_type;
Chris@16 42 typedef typename T::point_type point_type;
Chris@16 43
Chris@16 44 // Get the begin iterator
Chris@16 45 static inline iterator_type begin_points(const T& t) {
Chris@16 46 return t.begin();
Chris@16 47 }
Chris@16 48
Chris@16 49 // Get the end iterator
Chris@16 50 static inline iterator_type end_points(const T& t) {
Chris@16 51 return t.end();
Chris@16 52 }
Chris@16 53
Chris@16 54 // Get the number of sides of the polygon
Chris@16 55 static inline std::size_t size(const T& t) {
Chris@16 56 return t.size();
Chris@16 57 }
Chris@16 58
Chris@16 59 // Get the winding direction of the polygon
Chris@16 60 static inline winding_direction winding(const T&) {
Chris@16 61 return unknown_winding;
Chris@16 62 }
Chris@16 63 };
Chris@16 64
Chris@16 65 template <typename T>
Chris@16 66 struct polygon_traits_90 {
Chris@16 67 typedef typename polygon_90_traits<T>::coordinate_type coordinate_type;
Chris@16 68 typedef iterator_compact_to_points<typename polygon_90_traits<T>::compact_iterator_type, point_data<coordinate_type> > iterator_type;
Chris@16 69 typedef point_data<coordinate_type> point_type;
Chris@16 70
Chris@16 71 // Get the begin iterator
Chris@16 72 static inline iterator_type begin_points(const T& t) {
Chris@16 73 return iterator_type(polygon_90_traits<T>::begin_compact(t),
Chris@16 74 polygon_90_traits<T>::end_compact(t));
Chris@16 75 }
Chris@16 76
Chris@16 77 // Get the end iterator
Chris@16 78 static inline iterator_type end_points(const T& t) {
Chris@16 79 return iterator_type(polygon_90_traits<T>::end_compact(t),
Chris@16 80 polygon_90_traits<T>::end_compact(t));
Chris@16 81 }
Chris@16 82
Chris@16 83 // Get the number of sides of the polygon
Chris@16 84 static inline std::size_t size(const T& t) {
Chris@16 85 return polygon_90_traits<T>::size(t);
Chris@16 86 }
Chris@16 87
Chris@16 88 // Get the winding direction of the polygon
Chris@16 89 static inline winding_direction winding(const T& t) {
Chris@16 90 return polygon_90_traits<T>::winding(t);
Chris@16 91 }
Chris@16 92 };
Chris@16 93
Chris@16 94 #ifndef BOOST_VERY_LITTLE_SFINAE
Chris@16 95
Chris@16 96 template <typename T, typename enable = gtl_yes>
Chris@16 97 struct polygon_traits {};
Chris@16 98
Chris@16 99 template <typename T>
Chris@16 100 struct polygon_traits<T,
Chris@16 101 typename gtl_or_4<
Chris@16 102 typename gtl_same_type<typename geometry_concept<T>::type, polygon_concept>::type,
Chris@16 103 typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_concept>::type,
Chris@16 104 typename gtl_same_type<typename geometry_concept<T>::type, polygon_with_holes_concept>::type,
Chris@16 105 typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_with_holes_concept>::type
Chris@16 106 >::type> : public polygon_traits_general<T> {};
Chris@16 107
Chris@16 108 template <typename T>
Chris@16 109 struct polygon_traits< T,
Chris@16 110 typename gtl_or<
Chris@16 111 typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
Chris@16 112 typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type
Chris@16 113 >::type > : public polygon_traits_90<T> {};
Chris@16 114
Chris@16 115 #else
Chris@16 116
Chris@16 117 template <typename T, typename T_IF, typename T_ELSE>
Chris@16 118 struct gtl_ifelse {};
Chris@16 119 template <typename T_IF, typename T_ELSE>
Chris@16 120 struct gtl_ifelse<gtl_no, T_IF, T_ELSE> {
Chris@16 121 typedef T_ELSE type;
Chris@16 122 };
Chris@16 123 template <typename T_IF, typename T_ELSE>
Chris@16 124 struct gtl_ifelse<gtl_yes, T_IF, T_ELSE> {
Chris@16 125 typedef T_IF type;
Chris@16 126 };
Chris@16 127
Chris@16 128 template <typename T, typename enable = gtl_yes>
Chris@16 129 struct polygon_traits {};
Chris@16 130
Chris@16 131 template <typename T>
Chris@16 132 struct polygon_traits<T, typename gtl_or<typename gtl_or_4<
Chris@16 133 typename gtl_same_type<typename geometry_concept<T>::type, polygon_concept>::type,
Chris@16 134 typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_concept>::type,
Chris@16 135 typename gtl_same_type<typename geometry_concept<T>::type, polygon_with_holes_concept>::type,
Chris@16 136 typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_with_holes_concept>::type
Chris@16 137 >::type, typename gtl_or<
Chris@16 138 typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
Chris@16 139 typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type
Chris@16 140 >::type>::type > : public gtl_ifelse<typename gtl_or<
Chris@16 141 typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
Chris@16 142 typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type >::type,
Chris@16 143 polygon_traits_90<T>,
Chris@16 144 polygon_traits_general<T> >::type {
Chris@16 145 };
Chris@16 146
Chris@16 147 #endif
Chris@16 148
Chris@16 149 template <typename T, typename enable = void>
Chris@16 150 struct polygon_with_holes_traits {
Chris@16 151 typedef typename T::iterator_holes_type iterator_holes_type;
Chris@16 152 typedef typename T::hole_type hole_type;
Chris@16 153
Chris@16 154 // Get the begin iterator
Chris@16 155 static inline iterator_holes_type begin_holes(const T& t) {
Chris@16 156 return t.begin_holes();
Chris@16 157 }
Chris@16 158
Chris@16 159 // Get the end iterator
Chris@16 160 static inline iterator_holes_type end_holes(const T& t) {
Chris@16 161 return t.end_holes();
Chris@16 162 }
Chris@16 163
Chris@16 164 // Get the number of holes
Chris@16 165 static inline std::size_t size_holes(const T& t) {
Chris@16 166 return t.size_holes();
Chris@16 167 }
Chris@16 168 };
Chris@16 169
Chris@16 170 template <typename T, typename enable = void>
Chris@16 171 struct polygon_90_mutable_traits {
Chris@16 172
Chris@16 173 // Set the data of a polygon with the unique coordinates in an iterator, starting with an x
Chris@16 174 template <typename iT>
Chris@16 175 static inline T& set_compact(T& t, iT input_begin, iT input_end) {
Chris@16 176 t.set_compact(input_begin, input_end);
Chris@16 177 return t;
Chris@16 178 }
Chris@16 179
Chris@16 180 };
Chris@16 181
Chris@16 182 template <typename T>
Chris@16 183 struct polygon_90_mutable_traits<T, typename gtl_same_type<polygon_concept, typename geometry_concept<T>::type>::type> {
Chris@16 184 // Set the data of a polygon with the unique coordinates in an iterator, starting with an x
Chris@16 185 template <typename iT>
Chris@16 186 static inline T& set_compact(T& t, iT input_begin, iT input_end) {
Chris@16 187 typedef iterator_points_to_compact<iT, typename polygon_traits<T>::point_type> iTp;
Chris@16 188 t.set_points(iTp(polygon_traits<T>::begin_points(t)), iTp(polygon_traits<T>::end_points(t)));
Chris@16 189 return t;
Chris@16 190 }
Chris@16 191 };
Chris@16 192
Chris@16 193 template <typename T, typename enable = void>
Chris@16 194 struct polygon_mutable_traits {
Chris@16 195
Chris@16 196 // Set the data of a polygon with the unique coordinates in an iterator, starting with an x
Chris@16 197 template <typename iT>
Chris@16 198 static inline T& set_points(T& t, iT input_begin, iT input_end) {
Chris@16 199 t.set(input_begin, input_end);
Chris@16 200 return t;
Chris@16 201 }
Chris@16 202
Chris@16 203 };
Chris@16 204
Chris@16 205 template <typename T, typename enable = void>
Chris@16 206 struct polygon_with_holes_mutable_traits {
Chris@16 207
Chris@16 208 // Set the data of a polygon with the unique coordinates in an iterator, starting with an x
Chris@16 209 template <typename iT>
Chris@16 210 static inline T& set_holes(T& t, iT inputBegin, iT inputEnd) {
Chris@16 211 t.set_holes(inputBegin, inputEnd);
Chris@16 212 return t;
Chris@16 213 }
Chris@16 214
Chris@16 215 };
Chris@16 216 }
Chris@16 217 }
Chris@16 218 #include "isotropy.hpp"
Chris@16 219
Chris@16 220 //point
Chris@16 221 #include "point_data.hpp"
Chris@16 222 #include "point_traits.hpp"
Chris@16 223 #include "point_concept.hpp"
Chris@16 224
Chris@16 225 //interval
Chris@16 226 #include "interval_data.hpp"
Chris@16 227 #include "interval_traits.hpp"
Chris@16 228 #include "interval_concept.hpp"
Chris@16 229
Chris@16 230 //rectangle
Chris@16 231 #include "rectangle_data.hpp"
Chris@16 232 #include "rectangle_traits.hpp"
Chris@16 233 #include "rectangle_concept.hpp"
Chris@16 234
Chris@16 235 //algorithms needed by polygon types
Chris@16 236 #include "detail/iterator_points_to_compact.hpp"
Chris@16 237 #include "detail/iterator_compact_to_points.hpp"
Chris@16 238
Chris@16 239 //polygons
Chris@16 240 #include "polygon_45_data.hpp"
Chris@16 241 #include "polygon_data.hpp"
Chris@16 242 #include "polygon_90_data.hpp"
Chris@16 243 #include "polygon_90_with_holes_data.hpp"
Chris@16 244 #include "polygon_45_with_holes_data.hpp"
Chris@16 245 #include "polygon_with_holes_data.hpp"
Chris@16 246
Chris@16 247 namespace boost { namespace polygon{
Chris@16 248 struct polygon_concept {};
Chris@16 249 struct polygon_with_holes_concept {};
Chris@16 250 struct polygon_45_concept {};
Chris@16 251 struct polygon_45_with_holes_concept {};
Chris@16 252 struct polygon_90_concept {};
Chris@16 253 struct polygon_90_with_holes_concept {};
Chris@16 254
Chris@16 255
Chris@16 256 template <typename T>
Chris@16 257 struct is_polygon_90_type {
Chris@16 258 typedef typename geometry_concept<T>::type GC;
Chris@16 259 typedef typename gtl_same_type<polygon_90_concept, GC>::type type;
Chris@16 260 };
Chris@16 261
Chris@16 262 template <typename T>
Chris@16 263 struct is_polygon_45_type {
Chris@16 264 typedef typename geometry_concept<T>::type GC;
Chris@16 265 typedef typename gtl_or<typename is_polygon_90_type<T>::type,
Chris@16 266 typename gtl_same_type<polygon_45_concept, GC>::type>::type type;
Chris@16 267 };
Chris@16 268
Chris@16 269 template <typename T>
Chris@16 270 struct is_polygon_type {
Chris@16 271 typedef typename geometry_concept<T>::type GC;
Chris@16 272 typedef typename gtl_or<typename is_polygon_45_type<T>::type,
Chris@16 273 typename gtl_same_type<polygon_concept, GC>::type>::type type;
Chris@16 274 };
Chris@16 275
Chris@16 276 template <typename T>
Chris@16 277 struct is_polygon_90_with_holes_type {
Chris@16 278 typedef typename geometry_concept<T>::type GC;
Chris@16 279 typedef typename gtl_or<typename is_polygon_90_type<T>::type,
Chris@16 280 typename gtl_same_type<polygon_90_with_holes_concept, GC>::type>::type type;
Chris@16 281 };
Chris@16 282
Chris@16 283 template <typename T>
Chris@16 284 struct is_polygon_45_with_holes_type {
Chris@16 285 typedef typename geometry_concept<T>::type GC;
Chris@16 286 typedef typename gtl_or_3<typename is_polygon_90_with_holes_type<T>::type,
Chris@16 287 typename is_polygon_45_type<T>::type,
Chris@16 288 typename gtl_same_type<polygon_45_with_holes_concept, GC>::type>::type type;
Chris@16 289 };
Chris@16 290
Chris@16 291 template <typename T>
Chris@16 292 struct is_polygon_with_holes_type {
Chris@16 293 typedef typename geometry_concept<T>::type GC;
Chris@16 294 typedef typename gtl_or_3<typename is_polygon_45_with_holes_type<T>::type,
Chris@16 295 typename is_polygon_type<T>::type,
Chris@16 296 typename gtl_same_type<polygon_with_holes_concept, GC>::type>::type type;
Chris@16 297 };
Chris@16 298
Chris@16 299 template <typename T>
Chris@16 300 struct is_mutable_polygon_90_type {
Chris@16 301 typedef typename geometry_concept<T>::type GC;
Chris@16 302 typedef typename gtl_same_type<polygon_90_concept, GC>::type type;
Chris@16 303 };
Chris@16 304
Chris@16 305 template <typename T>
Chris@16 306 struct is_mutable_polygon_45_type {
Chris@16 307 typedef typename geometry_concept<T>::type GC;
Chris@16 308 typedef typename gtl_same_type<polygon_45_concept, GC>::type type;
Chris@16 309 };
Chris@16 310
Chris@16 311 template <typename T>
Chris@16 312 struct is_mutable_polygon_type {
Chris@16 313 typedef typename geometry_concept<T>::type GC;
Chris@16 314 typedef typename gtl_same_type<polygon_concept, GC>::type type;
Chris@16 315 };
Chris@16 316
Chris@16 317 template <typename T>
Chris@16 318 struct is_mutable_polygon_90_with_holes_type {
Chris@16 319 typedef typename geometry_concept<T>::type GC;
Chris@16 320 typedef typename gtl_same_type<polygon_90_with_holes_concept, GC>::type type;
Chris@16 321 };
Chris@16 322
Chris@16 323 template <typename T>
Chris@16 324 struct is_mutable_polygon_45_with_holes_type {
Chris@16 325 typedef typename geometry_concept<T>::type GC;
Chris@16 326 typedef typename gtl_same_type<polygon_45_with_holes_concept, GC>::type type;
Chris@16 327 };
Chris@16 328
Chris@16 329 template <typename T>
Chris@16 330 struct is_mutable_polygon_with_holes_type {
Chris@16 331 typedef typename geometry_concept<T>::type GC;
Chris@16 332 typedef typename gtl_same_type<polygon_with_holes_concept, GC>::type type;
Chris@16 333 };
Chris@16 334
Chris@16 335 template <typename T>
Chris@16 336 struct is_any_mutable_polygon_with_holes_type {
Chris@16 337 typedef typename gtl_or_3<typename is_mutable_polygon_90_with_holes_type<T>::type,
Chris@16 338 typename is_mutable_polygon_45_with_holes_type<T>::type,
Chris@16 339 typename is_mutable_polygon_with_holes_type<T>::type>::type type;
Chris@16 340 };
Chris@16 341 template <typename T>
Chris@16 342 struct is_any_mutable_polygon_without_holes_type {
Chris@16 343 typedef typename gtl_or_3<
Chris@16 344 typename is_mutable_polygon_90_type<T>::type,
Chris@16 345 typename is_mutable_polygon_45_type<T>::type,
Chris@16 346 typename is_mutable_polygon_type<T>::type>::type type; };
Chris@16 347
Chris@16 348 template <typename T>
Chris@16 349 struct is_any_mutable_polygon_type {
Chris@16 350 typedef typename gtl_or<typename is_any_mutable_polygon_with_holes_type<T>::type,
Chris@16 351 typename is_any_mutable_polygon_without_holes_type<T>::type>::type type;
Chris@16 352 };
Chris@16 353
Chris@16 354 template <typename T>
Chris@16 355 struct polygon_from_polygon_with_holes_type {};
Chris@16 356 template <>
Chris@16 357 struct polygon_from_polygon_with_holes_type<polygon_with_holes_concept> { typedef polygon_concept type; };
Chris@16 358 template <>
Chris@16 359 struct polygon_from_polygon_with_holes_type<polygon_45_with_holes_concept> { typedef polygon_45_concept type; };
Chris@16 360 template <>
Chris@16 361 struct polygon_from_polygon_with_holes_type<polygon_90_with_holes_concept> { typedef polygon_90_concept type; };
Chris@16 362
Chris@16 363 template <>
Chris@16 364 struct geometry_domain<polygon_45_concept> { typedef forty_five_domain type; };
Chris@16 365 template <>
Chris@16 366 struct geometry_domain<polygon_45_with_holes_concept> { typedef forty_five_domain type; };
Chris@16 367 template <>
Chris@16 368 struct geometry_domain<polygon_90_concept> { typedef manhattan_domain type; };
Chris@16 369 template <>
Chris@16 370 struct geometry_domain<polygon_90_with_holes_concept> { typedef manhattan_domain type; };
Chris@16 371
Chris@16 372 template <typename domain_type, typename coordinate_type>
Chris@16 373 struct distance_type_by_domain { typedef typename coordinate_traits<coordinate_type>::coordinate_distance type; };
Chris@16 374 template <typename coordinate_type>
Chris@16 375 struct distance_type_by_domain<manhattan_domain, coordinate_type> {
Chris@16 376 typedef typename coordinate_traits<coordinate_type>::coordinate_difference type; };
Chris@16 377
Chris@16 378 // \brief Sets the boundary of the polygon to the points in the iterator range
Chris@16 379 // \tparam T A type that models polygon_concept
Chris@16 380 // \tparam iT Iterator type over objects that model point_concept
Chris@16 381 // \param t The polygon to set
Chris@16 382 // \param begin_points The start of the range of points
Chris@16 383 // \param end_points The end of the range of points
Chris@16 384
Chris@16 385 /// \relatesalso polygon_concept
Chris@16 386 template <typename T, typename iT>
Chris@16 387 typename enable_if <typename is_any_mutable_polygon_type<T>::type, T>::type &
Chris@16 388 set_points(T& t, iT begin_points, iT end_points) {
Chris@16 389 polygon_mutable_traits<T>::set_points(t, begin_points, end_points);
Chris@16 390 return t;
Chris@16 391 }
Chris@16 392
Chris@16 393 // \brief Sets the boundary of the polygon to the non-redundant coordinates in the iterator range
Chris@16 394 // \tparam T A type that models polygon_90_concept
Chris@16 395 // \tparam iT Iterator type over objects that model coordinate_concept
Chris@16 396 // \param t The polygon to set
Chris@16 397 // \param begin_compact_coordinates The start of the range of coordinates
Chris@16 398 // \param end_compact_coordinates The end of the range of coordinates
Chris@16 399
Chris@16 400 /// \relatesalso polygon_90_concept
Chris@16 401 template <typename T, typename iT>
Chris@16 402 typename enable_if <typename gtl_or<
Chris@16 403 typename is_mutable_polygon_90_type<T>::type,
Chris@16 404 typename is_mutable_polygon_90_with_holes_type<T>::type>::type, T>::type &
Chris@16 405 set_compact(T& t, iT begin_compact_coordinates, iT end_compact_coordinates) {
Chris@16 406 polygon_90_mutable_traits<T>::set_compact(t, begin_compact_coordinates, end_compact_coordinates);
Chris@16 407 return t;
Chris@16 408 }
Chris@16 409
Chris@16 410 /// \relatesalso polygon_with_holes_concept
Chris@16 411 template <typename T, typename iT>
Chris@16 412 typename enable_if< typename gtl_and <
Chris@16 413 typename is_any_mutable_polygon_with_holes_type<T>::type,
Chris@16 414 typename gtl_different_type<typename geometry_domain<typename geometry_concept<T>::type>::type,
Chris@16 415 manhattan_domain>::type>::type,
Chris@16 416 T>::type &
Chris@16 417 set_compact(T& t, iT begin_compact_coordinates, iT end_compact_coordinates) {
Chris@16 418 iterator_compact_to_points<iT, point_data<typename polygon_traits<T>::coordinate_type> >
Chris@16 419 itrb(begin_compact_coordinates, end_compact_coordinates),
Chris@16 420 itre(end_compact_coordinates, end_compact_coordinates);
Chris@16 421 return set_points(t, itrb, itre);
Chris@16 422 }
Chris@16 423
Chris@16 424 /// \relatesalso polygon_with_holes_concept
Chris@16 425 template <typename T, typename iT>
Chris@16 426 typename enable_if <typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type &
Chris@16 427 set_holes(T& t, iT begin_holes, iT end_holes) {
Chris@16 428 polygon_with_holes_mutable_traits<T>::set_holes(t, begin_holes, end_holes);
Chris@16 429 return t;
Chris@16 430 }
Chris@16 431
Chris@16 432 /// \relatesalso polygon_90_concept
Chris@16 433 template <typename T>
Chris@16 434 typename polygon_90_traits<T>::compact_iterator_type
Chris@16 435 begin_compact(const T& polygon,
Chris@16 436 typename enable_if<
Chris@16 437 typename gtl_and <typename is_polygon_with_holes_type<T>::type,
Chris@16 438 typename gtl_same_type<typename geometry_domain<typename geometry_concept<T>::type>::type,
Chris@16 439 manhattan_domain>::type>::type>::type * = 0
Chris@16 440 ) {
Chris@16 441 return polygon_90_traits<T>::begin_compact(polygon);
Chris@16 442 }
Chris@16 443
Chris@16 444 /// \relatesalso polygon_90_concept
Chris@16 445 template <typename T>
Chris@16 446 typename polygon_90_traits<T>::compact_iterator_type
Chris@16 447 end_compact(const T& polygon,
Chris@16 448 typename enable_if<
Chris@16 449 typename gtl_and <typename is_polygon_with_holes_type<T>::type,
Chris@16 450 typename gtl_same_type<typename geometry_domain<typename geometry_concept<T>::type>::type,
Chris@16 451 manhattan_domain>::type>::type>::type * = 0
Chris@16 452 ) {
Chris@16 453 return polygon_90_traits<T>::end_compact(polygon);
Chris@16 454 }
Chris@16 455
Chris@16 456 /// \relatesalso polygon_concept
Chris@16 457 template <typename T>
Chris@16 458 typename enable_if < typename gtl_if<
Chris@16 459 typename is_polygon_with_holes_type<T>::type>::type,
Chris@16 460 typename polygon_traits<T>::iterator_type>::type
Chris@16 461 begin_points(const T& polygon) {
Chris@16 462 return polygon_traits<T>::begin_points(polygon);
Chris@16 463 }
Chris@16 464
Chris@16 465 /// \relatesalso polygon_concept
Chris@16 466 template <typename T>
Chris@16 467 typename enable_if < typename gtl_if<
Chris@16 468 typename is_polygon_with_holes_type<T>::type>::type,
Chris@16 469 typename polygon_traits<T>::iterator_type>::type
Chris@16 470 end_points(const T& polygon) {
Chris@16 471 return polygon_traits<T>::end_points(polygon);
Chris@16 472 }
Chris@16 473
Chris@16 474 /// \relatesalso polygon_concept
Chris@16 475 template <typename T>
Chris@16 476 typename enable_if <typename is_polygon_with_holes_type<T>::type,
Chris@16 477 std::size_t>::type
Chris@16 478 size(const T& polygon) {
Chris@16 479 return polygon_traits<T>::size(polygon);
Chris@16 480 }
Chris@16 481
Chris@16 482 /// \relatesalso polygon_with_holes_concept
Chris@16 483 template <typename T>
Chris@16 484 typename enable_if < typename gtl_if<
Chris@16 485 typename is_polygon_with_holes_type<T>::type>::type,
Chris@16 486 typename polygon_with_holes_traits<T>::iterator_holes_type>::type
Chris@16 487 begin_holes(const T& polygon) {
Chris@16 488 return polygon_with_holes_traits<T>::begin_holes(polygon);
Chris@16 489 }
Chris@16 490
Chris@16 491 /// \relatesalso polygon_with_holes_concept
Chris@16 492 template <typename T>
Chris@16 493 typename enable_if < typename gtl_if<
Chris@16 494 typename is_polygon_with_holes_type<T>::type>::type,
Chris@16 495 typename polygon_with_holes_traits<T>::iterator_holes_type>::type
Chris@16 496 end_holes(const T& polygon) {
Chris@16 497 return polygon_with_holes_traits<T>::end_holes(polygon);
Chris@16 498 }
Chris@16 499
Chris@16 500 /// \relatesalso polygon_with_holes_concept
Chris@16 501 template <typename T>
Chris@16 502 typename enable_if <typename is_polygon_with_holes_type<T>::type,
Chris@16 503 std::size_t>::type
Chris@16 504 size_holes(const T& polygon) {
Chris@16 505 return polygon_with_holes_traits<T>::size_holes(polygon);
Chris@16 506 }
Chris@16 507
Chris@16 508 // \relatesalso polygon_concept
Chris@16 509 template <typename T1, typename T2>
Chris@16 510 typename enable_if<
Chris@16 511 typename gtl_and< typename is_mutable_polygon_type<T1>::type,
Chris@16 512 typename is_polygon_type<T2>::type>::type, T1>::type &
Chris@16 513 assign(T1& lvalue, const T2& rvalue) {
Chris@16 514 polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue),
Chris@16 515 polygon_traits<T2>::end_points(rvalue));
Chris@16 516 return lvalue;
Chris@16 517 }
Chris@16 518
Chris@16 519 // \relatesalso polygon_with_holes_concept
Chris@16 520 template <typename T1, typename T2>
Chris@16 521 typename enable_if<
Chris@16 522 typename gtl_and< typename is_mutable_polygon_with_holes_type<T1>::type,
Chris@16 523 typename is_polygon_with_holes_type<T2>::type>::type, T1>::type &
Chris@16 524 assign(T1& lvalue, const T2& rvalue) {
Chris@16 525 polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue),
Chris@16 526 polygon_traits<T2>::end_points(rvalue));
Chris@16 527 polygon_with_holes_mutable_traits<T1>::set_holes(lvalue, polygon_with_holes_traits<T2>::begin_holes(rvalue),
Chris@16 528 polygon_with_holes_traits<T2>::end_holes(rvalue));
Chris@16 529 return lvalue;
Chris@16 530 }
Chris@16 531
Chris@16 532 // \relatesalso polygon_45_concept
Chris@16 533 template <typename T1, typename T2>
Chris@16 534 typename enable_if< typename gtl_and< typename is_mutable_polygon_45_type<T1>::type, typename is_polygon_45_type<T2>::type>::type, T1>::type &
Chris@16 535 assign(T1& lvalue, const T2& rvalue) {
Chris@16 536 polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue),
Chris@16 537 polygon_traits<T2>::end_points(rvalue));
Chris@16 538 return lvalue;
Chris@16 539 }
Chris@16 540
Chris@16 541 // \relatesalso polygon_45_with_holes_concept
Chris@16 542 template <typename T1, typename T2>
Chris@16 543 typename enable_if<
Chris@16 544 typename gtl_and< typename is_mutable_polygon_45_with_holes_type<T1>::type,
Chris@16 545 typename is_polygon_45_with_holes_type<T2>::type>::type, T1>::type &
Chris@16 546 assign(T1& lvalue, const T2& rvalue) {
Chris@16 547 polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue),
Chris@16 548 polygon_traits<T2>::end_points(rvalue));
Chris@16 549 polygon_with_holes_mutable_traits<T1>::set_holes(lvalue, polygon_with_holes_traits<T2>::begin_holes(rvalue),
Chris@16 550 polygon_with_holes_traits<T2>::end_holes(rvalue));
Chris@16 551 return lvalue;
Chris@16 552 }
Chris@16 553
Chris@16 554 // \relatesalso polygon_90_concept
Chris@16 555 template <typename T1, typename T2>
Chris@16 556 typename enable_if<
Chris@16 557 typename gtl_and< typename is_mutable_polygon_90_type<T1>::type,
Chris@16 558 typename is_polygon_90_type<T2>::type>::type, T1>::type &
Chris@16 559 assign(T1& lvalue, const T2& rvalue) {
Chris@16 560 polygon_90_mutable_traits<T1>::set_compact(lvalue, polygon_90_traits<T2>::begin_compact(rvalue),
Chris@16 561 polygon_90_traits<T2>::end_compact(rvalue));
Chris@16 562 return lvalue;
Chris@16 563 }
Chris@16 564
Chris@16 565 // \relatesalso polygon_90_with_holes_concept
Chris@16 566 template <typename T1, typename T2>
Chris@16 567 typename enable_if<
Chris@16 568 typename gtl_and< typename is_mutable_polygon_90_with_holes_type<T1>::type,
Chris@16 569 typename is_polygon_90_with_holes_type<T2>::type>::type, T1>::type &
Chris@16 570 assign(T1& lvalue, const T2& rvalue) {
Chris@16 571 polygon_90_mutable_traits<T1>::set_compact(lvalue, polygon_90_traits<T2>::begin_compact(rvalue),
Chris@16 572 polygon_90_traits<T2>::end_compact(rvalue));
Chris@16 573 polygon_with_holes_mutable_traits<T1>::set_holes(lvalue, polygon_with_holes_traits<T2>::begin_holes(rvalue),
Chris@16 574 polygon_with_holes_traits<T2>::end_holes(rvalue));
Chris@16 575 return lvalue;
Chris@16 576 }
Chris@16 577
Chris@16 578 // \relatesalso polygon_90_concept
Chris@16 579 template <typename T1, typename T2>
Chris@16 580 typename enable_if<
Chris@16 581 typename gtl_and< typename is_any_mutable_polygon_type<T1>::type,
Chris@16 582 typename is_rectangle_concept<typename geometry_concept<T2>::type>::type>::type, T1>::type &
Chris@16 583 assign(T1& polygon, const T2& rect) {
Chris@16 584 typedef point_data<typename polygon_traits<T1>::coordinate_type> PT;
Chris@16 585 PT points[4] = {PT(xl(rect), yl(rect)), PT(xh(rect), yl(rect)), PT(xh(rect), yh(rect)), PT(xl(rect), yh(rect))};
Chris@16 586 set_points(polygon, points, points+4);
Chris@16 587 return polygon;
Chris@16 588 }
Chris@16 589
Chris@16 590 /// \relatesalso polygon_90_concept
Chris@16 591 template <typename polygon_type, typename point_type>
Chris@16 592 typename enable_if< typename gtl_and< typename is_mutable_polygon_90_type<polygon_type>::type,
Chris@16 593 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
Chris@16 594 polygon_type>::type &
Chris@16 595 convolve(polygon_type& polygon, const point_type& point) {
Chris@16 596 std::vector<typename polygon_90_traits<polygon_type>::coordinate_type> coords;
Chris@16 597 coords.reserve(size(polygon));
Chris@16 598 bool pingpong = true;
Chris@16 599 for(typename polygon_90_traits<polygon_type>::compact_iterator_type iter = begin_compact(polygon);
Chris@16 600 iter != end_compact(polygon); ++iter) {
Chris@16 601 coords.push_back((*iter) + (pingpong ? x(point) : y(point)));
Chris@16 602 pingpong = !pingpong;
Chris@16 603 }
Chris@16 604 polygon_90_mutable_traits<polygon_type>::set_compact(polygon, coords.begin(), coords.end());
Chris@16 605 return polygon;
Chris@16 606 }
Chris@16 607
Chris@16 608 /// \relatesalso polygon_concept
Chris@16 609 template <typename polygon_type, typename point_type>
Chris@16 610 typename enable_if< typename gtl_and< typename gtl_or<
Chris@16 611 typename is_mutable_polygon_45_type<polygon_type>::type,
Chris@16 612 typename is_mutable_polygon_type<polygon_type>::type>::type,
Chris@16 613 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
Chris@16 614 polygon_type>::type &
Chris@16 615 convolve(polygon_type& polygon, const point_type& point) {
Chris@16 616 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
Chris@16 617 points.reserve(size(polygon));
Chris@16 618 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
Chris@16 619 iter != end_points(polygon); ++iter) {
Chris@16 620 points.push_back(*iter);
Chris@16 621 convolve(points.back(), point);
Chris@16 622 }
Chris@16 623 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
Chris@16 624 return polygon;
Chris@16 625 }
Chris@16 626
Chris@16 627 /// \relatesalso polygon_with_holes_concept
Chris@16 628 template <typename polygon_type, typename point_type>
Chris@16 629 typename enable_if<
Chris@16 630 typename gtl_and< typename is_any_mutable_polygon_with_holes_type<polygon_type>::type,
Chris@16 631 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
Chris@16 632 polygon_type>::type &
Chris@16 633 convolve(polygon_type& polygon, const point_type& point) {
Chris@16 634 typedef typename polygon_with_holes_traits<polygon_type>::hole_type hole_type;
Chris@16 635 hole_type h;
Chris@16 636 set_points(h, begin_points(polygon), end_points(polygon));
Chris@16 637 convolve(h, point);
Chris@16 638 std::vector<hole_type> holes;
Chris@16 639 holes.reserve(size_holes(polygon));
Chris@16 640 for(typename polygon_with_holes_traits<polygon_type>::iterator_holes_type itr = begin_holes(polygon);
Chris@16 641 itr != end_holes(polygon); ++itr) {
Chris@16 642 holes.push_back(*itr);
Chris@16 643 convolve(holes.back(), point);
Chris@16 644 }
Chris@16 645 assign(polygon, h);
Chris@16 646 set_holes(polygon, holes.begin(), holes.end());
Chris@16 647 return polygon;
Chris@16 648 }
Chris@16 649
Chris@16 650 /// \relatesalso polygon_concept
Chris@16 651 template <typename T>
Chris@16 652 typename enable_if< typename is_any_mutable_polygon_type<T>::type, T>::type &
Chris@16 653 move(T& polygon, orientation_2d orient, typename polygon_traits<T>::coordinate_type displacement) {
Chris@16 654 typedef typename polygon_traits<T>::coordinate_type Unit;
Chris@16 655 if(orient == HORIZONTAL) return convolve(polygon, point_data<Unit>(displacement, Unit(0)));
Chris@16 656 return convolve(polygon, point_data<Unit>(Unit(0), displacement));
Chris@16 657 }
Chris@16 658
Chris@16 659 /// \relatesalso polygon_concept
Chris@16 660 /// \brief Applies a transformation to the polygon.
Chris@16 661 /// \tparam polygon_type A type that models polygon_concept
Chris@16 662 /// \tparam transform_type A type that may be either axis_transformation or transformation or that overloads point_concept::transform
Chris@16 663 /// \param polygon The polygon to transform
Chris@16 664 /// \param tr The transformation to apply
Chris@16 665 template <typename polygon_type, typename transform_type>
Chris@16 666 typename enable_if< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, polygon_type>::type &
Chris@16 667 transform(polygon_type& polygon, const transform_type& tr) {
Chris@16 668 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
Chris@16 669 points.reserve(size(polygon));
Chris@16 670 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
Chris@16 671 iter != end_points(polygon); ++iter) {
Chris@16 672 points.push_back(*iter);
Chris@16 673 transform(points.back(), tr);
Chris@16 674 }
Chris@16 675 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
Chris@16 676 return polygon;
Chris@16 677 }
Chris@16 678
Chris@16 679 /// \relatesalso polygon_with_holes_concept
Chris@16 680 template <typename T, typename transform_type>
Chris@16 681 typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type &
Chris@16 682 transform(T& polygon, const transform_type& tr) {
Chris@16 683 typedef typename polygon_with_holes_traits<T>::hole_type hole_type;
Chris@16 684 hole_type h;
Chris@16 685 set_points(h, begin_points(polygon), end_points(polygon));
Chris@16 686 transform(h, tr);
Chris@16 687 std::vector<hole_type> holes;
Chris@16 688 holes.reserve(size_holes(polygon));
Chris@16 689 for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon);
Chris@16 690 itr != end_holes(polygon); ++itr) {
Chris@16 691 holes.push_back(*itr);
Chris@16 692 transform(holes.back(), tr);
Chris@16 693 }
Chris@16 694 assign(polygon, h);
Chris@16 695 set_holes(polygon, holes.begin(), holes.end());
Chris@16 696 return polygon;
Chris@16 697 }
Chris@16 698
Chris@16 699 template <typename polygon_type>
Chris@16 700 typename enable_if< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, polygon_type>::type &
Chris@16 701 scale_up(polygon_type& polygon, typename coordinate_traits<typename polygon_traits<polygon_type>::coordinate_type>::unsigned_area_type factor) {
Chris@16 702 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
Chris@16 703 points.reserve(size(polygon));
Chris@16 704 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
Chris@16 705 iter != end_points(polygon); ++iter) {
Chris@16 706 points.push_back(*iter);
Chris@16 707 scale_up(points.back(), factor);
Chris@16 708 }
Chris@16 709 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
Chris@16 710 return polygon;
Chris@16 711 }
Chris@16 712
Chris@16 713 template <typename T>
Chris@16 714 typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type &
Chris@16 715 scale_up(T& polygon, typename coordinate_traits<typename polygon_traits<T>::coordinate_type>::unsigned_area_type factor) {
Chris@16 716 typedef typename polygon_with_holes_traits<T>::hole_type hole_type;
Chris@16 717 hole_type h;
Chris@16 718 set_points(h, begin_points(polygon), end_points(polygon));
Chris@16 719 scale_up(h, factor);
Chris@16 720 std::vector<hole_type> holes;
Chris@16 721 holes.reserve(size_holes(polygon));
Chris@16 722 for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon);
Chris@16 723 itr != end_holes(polygon); ++itr) {
Chris@16 724 holes.push_back(*itr);
Chris@16 725 scale_up(holes.back(), factor);
Chris@16 726 }
Chris@16 727 assign(polygon, h);
Chris@16 728 set_holes(polygon, holes.begin(), holes.end());
Chris@16 729 return polygon;
Chris@16 730 }
Chris@16 731
Chris@16 732 //scale non-45 down
Chris@16 733 template <typename polygon_type>
Chris@16 734 typename enable_if<
Chris@16 735 typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type,
Chris@16 736 typename gtl_not<typename gtl_same_type
Chris@16 737 < forty_five_domain,
Chris@16 738 typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type>::type,
Chris@16 739 polygon_type>::type &
Chris@16 740 scale_down(polygon_type& polygon, typename coordinate_traits<typename polygon_traits<polygon_type>::coordinate_type>::unsigned_area_type factor) {
Chris@16 741 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
Chris@16 742 points.reserve(size(polygon));
Chris@16 743 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
Chris@16 744 iter != end_points(polygon); ++iter) {
Chris@16 745 points.push_back(*iter);
Chris@16 746 scale_down(points.back(), factor);
Chris@16 747 }
Chris@16 748 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
Chris@16 749 return polygon;
Chris@16 750 }
Chris@16 751
Chris@16 752 template <typename Unit>
Chris@16 753 Unit local_abs(Unit value) { return value < 0 ? (Unit)-value : value; }
Chris@16 754
Chris@16 755 template <typename Unit>
Chris@16 756 void snap_point_vector_to_45(std::vector<point_data<Unit> >& pts) {
Chris@16 757 typedef point_data<Unit> Point;
Chris@16 758 if(pts.size() < 3) { pts.clear(); return; }
Chris@16 759 typename std::vector<point_data<Unit> >::iterator endLocation = std::unique(pts.begin(), pts.end());
Chris@16 760 if(endLocation != pts.end()){
Chris@16 761 pts.resize(endLocation - pts.begin());
Chris@16 762 }
Chris@16 763 if(pts.back() == pts[0]) pts.pop_back();
Chris@16 764 //iterate over point triplets
Chris@16 765 int numPts = pts.size();
Chris@16 766 bool wrap_around = false;
Chris@16 767 for(int i = 0; i < numPts; ++i) {
Chris@16 768 Point& pt1 = pts[i];
Chris@16 769 Point& pt2 = pts[(i + 1) % numPts];
Chris@16 770 Point& pt3 = pts[(i + 2) % numPts];
Chris@16 771 //check if non-45 edge
Chris@16 772 Unit deltax = x(pt2) - x(pt1);
Chris@16 773 Unit deltay = y(pt2) - y(pt1);
Chris@16 774 if(deltax && deltay &&
Chris@16 775 local_abs(deltax) != local_abs(deltay)) {
Chris@16 776 //adjust the middle point
Chris@16 777 Unit ndx = x(pt3) - x(pt2);
Chris@16 778 Unit ndy = y(pt3) - y(pt2);
Chris@16 779 if(ndx && ndy) {
Chris@16 780 Unit diff = local_abs(local_abs(deltax) - local_abs(deltay));
Chris@16 781 Unit halfdiff = diff/2;
Chris@16 782 if((deltax > 0 && deltay > 0) ||
Chris@16 783 (deltax < 0 && deltay < 0)) {
Chris@16 784 //previous edge is rising slope
Chris@16 785 if(local_abs(deltax + halfdiff + (diff % 2)) ==
Chris@16 786 local_abs(deltay - halfdiff)) {
Chris@16 787 x(pt2, x(pt2) + halfdiff + (diff % 2));
Chris@16 788 y(pt2, y(pt2) - halfdiff);
Chris@16 789 } else if(local_abs(deltax - halfdiff - (diff % 2)) ==
Chris@16 790 local_abs(deltay + halfdiff)) {
Chris@16 791 x(pt2, x(pt2) - halfdiff - (diff % 2));
Chris@16 792 y(pt2, y(pt2) + halfdiff);
Chris@16 793 } else{
Chris@16 794 //std::cout << "fail1\n";
Chris@16 795 }
Chris@16 796 } else {
Chris@16 797 //previous edge is falling slope
Chris@16 798 if(local_abs(deltax + halfdiff + (diff % 2)) ==
Chris@16 799 local_abs(deltay + halfdiff)) {
Chris@16 800 x(pt2, x(pt2) + halfdiff + (diff % 2));
Chris@16 801 y(pt2, y(pt2) + halfdiff);
Chris@16 802 } else if(local_abs(deltax - halfdiff - (diff % 2)) ==
Chris@16 803 local_abs(deltay - halfdiff)) {
Chris@16 804 x(pt2, x(pt2) - halfdiff - (diff % 2));
Chris@16 805 y(pt2, y(pt2) - halfdiff);
Chris@16 806 } else {
Chris@16 807 //std::cout << "fail2\n";
Chris@16 808 }
Chris@16 809 }
Chris@16 810 if(i == numPts - 1 && (diff % 2)) {
Chris@16 811 //we have a wrap around effect
Chris@16 812 if(!wrap_around) {
Chris@16 813 wrap_around = true;
Chris@16 814 i = -1;
Chris@16 815 }
Chris@16 816 }
Chris@16 817 } else if(ndx) {
Chris@16 818 //next edge is horizontal
Chris@16 819 //find the x value for pt1 that would make the abs(deltax) == abs(deltay)
Chris@16 820 Unit newDeltaX = local_abs(deltay);
Chris@16 821 if(deltax < 0) newDeltaX *= -1;
Chris@16 822 x(pt2, x(pt1) + newDeltaX);
Chris@16 823 } else { //ndy
Chris@16 824 //next edge is vertical
Chris@16 825 //find the y value for pt1 that would make the abs(deltax) == abs(deltay)
Chris@16 826 Unit newDeltaY = local_abs(deltax);
Chris@16 827 if(deltay < 0) newDeltaY *= -1;
Chris@16 828 y(pt2, y(pt1) + newDeltaY);
Chris@16 829 }
Chris@16 830 }
Chris@16 831 }
Chris@16 832 }
Chris@16 833
Chris@16 834 template <typename polygon_type>
Chris@16 835 typename enable_if< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, polygon_type>::type &
Chris@16 836 snap_to_45(polygon_type& polygon) {
Chris@16 837 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
Chris@16 838 points.reserve(size(polygon));
Chris@16 839 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
Chris@16 840 iter != end_points(polygon); ++iter) {
Chris@16 841 points.push_back(*iter);
Chris@16 842 }
Chris@16 843 snap_point_vector_to_45(points);
Chris@16 844 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
Chris@16 845 return polygon;
Chris@16 846 }
Chris@16 847
Chris@16 848 template <typename polygon_type>
Chris@16 849 typename enable_if< typename is_any_mutable_polygon_with_holes_type<polygon_type>::type, polygon_type>::type &
Chris@16 850 snap_to_45(polygon_type& polygon) {
Chris@16 851 typedef typename polygon_with_holes_traits<polygon_type>::hole_type hole_type;
Chris@16 852 hole_type h;
Chris@16 853 set_points(h, begin_points(polygon), end_points(polygon));
Chris@16 854 snap_to_45(h);
Chris@16 855 std::vector<hole_type> holes;
Chris@16 856 holes.reserve(size_holes(polygon));
Chris@16 857 for(typename polygon_with_holes_traits<polygon_type>::iterator_holes_type itr = begin_holes(polygon);
Chris@16 858 itr != end_holes(polygon); ++itr) {
Chris@16 859 holes.push_back(*itr);
Chris@16 860 snap_to_45(holes.back());
Chris@16 861 }
Chris@16 862 assign(polygon, h);
Chris@16 863 set_holes(polygon, holes.begin(), holes.end());
Chris@16 864 return polygon;
Chris@16 865 }
Chris@16 866
Chris@16 867 //scale specifically 45 down
Chris@16 868 template <typename polygon_type>
Chris@16 869 typename enable_if<
Chris@16 870 typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type,
Chris@16 871 typename gtl_same_type
Chris@16 872 < forty_five_domain,
Chris@16 873 typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type,
Chris@16 874 polygon_type>::type &
Chris@16 875 scale_down(polygon_type& polygon, typename coordinate_traits<typename polygon_traits<polygon_type>::coordinate_type>::unsigned_area_type factor) {
Chris@16 876 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
Chris@16 877 points.reserve(size(polygon));
Chris@16 878 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
Chris@16 879 iter != end_points(polygon); ++iter) {
Chris@16 880 points.push_back(*iter);
Chris@16 881 scale_down(points.back(), factor);
Chris@16 882 }
Chris@16 883 snap_point_vector_to_45(points);
Chris@16 884 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
Chris@16 885 return polygon;
Chris@16 886 }
Chris@16 887
Chris@16 888 template <typename T>
Chris@16 889 typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type &
Chris@16 890 scale_down(T& polygon, typename coordinate_traits<typename polygon_traits<T>::coordinate_type>::unsigned_area_type factor) {
Chris@16 891 typedef typename polygon_with_holes_traits<T>::hole_type hole_type;
Chris@16 892 hole_type h;
Chris@16 893 set_points(h, begin_points(polygon), end_points(polygon));
Chris@16 894 scale_down(h, factor);
Chris@16 895 std::vector<hole_type> holes;
Chris@16 896 holes.reserve(size_holes(polygon));
Chris@16 897 for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon);
Chris@16 898 itr != end_holes(polygon); ++itr) {
Chris@16 899 holes.push_back(*itr);
Chris@16 900 scale_down(holes.back(), factor);
Chris@16 901 }
Chris@16 902 assign(polygon, h);
Chris@16 903 set_holes(polygon, holes.begin(), holes.end());
Chris@16 904 return polygon;
Chris@16 905 }
Chris@16 906
Chris@16 907 //scale non-45
Chris@16 908 template <typename polygon_type>
Chris@16 909 typename enable_if<
Chris@16 910 typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type,
Chris@16 911 typename gtl_not<typename gtl_same_type
Chris@16 912 < forty_five_domain,
Chris@16 913 typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type>::type,
Chris@16 914 polygon_type>::type &
Chris@16 915 scale(polygon_type& polygon, double factor) {
Chris@16 916 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
Chris@16 917 points.reserve(size(polygon));
Chris@16 918 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
Chris@16 919 iter != end_points(polygon); ++iter) {
Chris@16 920 points.push_back(*iter);
Chris@16 921 scale(points.back(), anisotropic_scale_factor<double>(factor, factor));
Chris@16 922 }
Chris@16 923 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
Chris@16 924 return polygon;
Chris@16 925 }
Chris@16 926
Chris@16 927 //scale specifically 45
Chris@16 928 template <typename polygon_type>
Chris@16 929 polygon_type&
Chris@16 930 scale(polygon_type& polygon, double factor,
Chris@16 931 typename enable_if<
Chris@16 932 typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type,
Chris@16 933 typename gtl_same_type
Chris@16 934 < forty_five_domain,
Chris@16 935 typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type>::type * = 0
Chris@16 936 ) {
Chris@16 937 std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
Chris@16 938 points.reserve(size(polygon));
Chris@16 939 for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
Chris@16 940 iter != end_points(polygon); ++iter) {
Chris@16 941 points.push_back(*iter);
Chris@16 942 scale(points.back(), anisotropic_scale_factor<double>(factor, factor));
Chris@16 943 }
Chris@16 944 snap_point_vector_to_45(points);
Chris@16 945 polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
Chris@16 946 return polygon;
Chris@16 947 }
Chris@16 948
Chris@16 949 template <typename T>
Chris@16 950 T&
Chris@16 951 scale(T& polygon, double factor,
Chris@16 952 typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type>::type * = 0
Chris@16 953 ) {
Chris@16 954 typedef typename polygon_with_holes_traits<T>::hole_type hole_type;
Chris@16 955 hole_type h;
Chris@16 956 set_points(h, begin_points(polygon), end_points(polygon));
Chris@16 957 scale(h, factor);
Chris@16 958 std::vector<hole_type> holes;
Chris@16 959 holes.reserve(size_holes(polygon));
Chris@16 960 for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon);
Chris@16 961 itr != end_holes(polygon); ++itr) {
Chris@16 962 holes.push_back(*itr);
Chris@16 963 scale(holes.back(), factor);
Chris@16 964 }
Chris@16 965 assign(polygon, h);
Chris@16 966 set_holes(polygon, holes.begin(), holes.end());
Chris@16 967 return polygon;
Chris@16 968 }
Chris@16 969
Chris@16 970 template <typename iterator_type, typename area_type>
Chris@16 971 static area_type
Chris@16 972 point_sequence_area(iterator_type begin_range, iterator_type end_range) {
Chris@16 973 typedef typename std::iterator_traits<iterator_type>::value_type point_type;
Chris@16 974 if(begin_range == end_range) return area_type(0);
Chris@16 975 point_type first = *begin_range;
Chris@16 976 point_type previous = first;
Chris@16 977 ++begin_range;
Chris@16 978 // Initialize trapezoid base line
Chris@16 979 area_type y_base = (area_type)y(first);
Chris@16 980 // Initialize area accumulator
Chris@16 981
Chris@16 982 area_type area(0);
Chris@16 983 while (begin_range != end_range) {
Chris@16 984 area_type x1 = (area_type)x(previous);
Chris@16 985 area_type x2 = (area_type)x(*begin_range);
Chris@16 986 #ifdef BOOST_POLYGON_ICC
Chris@16 987 #pragma warning (push)
Chris@16 988 #pragma warning (disable:1572)
Chris@16 989 #endif
Chris@16 990 if(x1 != x2) {
Chris@16 991 #ifdef BOOST_POLYGON_ICC
Chris@16 992 #pragma warning (pop)
Chris@16 993 #endif
Chris@16 994 // do trapezoid area accumulation
Chris@16 995 area += (x2 - x1) * (((area_type)y(*begin_range) - y_base) +
Chris@16 996 ((area_type)y(previous) - y_base)) / 2;
Chris@16 997 }
Chris@16 998 previous = *begin_range;
Chris@16 999 // go to next point
Chris@16 1000 ++begin_range;
Chris@16 1001 }
Chris@16 1002 //wrap around to evaluate the edge between first and last if not closed
Chris@16 1003 if(!equivalence(first, previous)) {
Chris@16 1004 area_type x1 = (area_type)x(previous);
Chris@16 1005 area_type x2 = (area_type)x(first);
Chris@16 1006 area += (x2 - x1) * (((area_type)y(first) - y_base) +
Chris@16 1007 ((area_type)y(previous) - y_base)) / 2;
Chris@16 1008 }
Chris@16 1009 return area;
Chris@16 1010 }
Chris@16 1011
Chris@16 1012 template <typename T>
Chris@16 1013 typename enable_if<
Chris@16 1014 typename is_polygon_with_holes_type<T>::type,
Chris@16 1015 typename area_type_by_domain< typename geometry_domain<typename geometry_concept<T>::type>::type,
Chris@16 1016 typename polygon_traits<T>::coordinate_type>::type>::type
Chris@16 1017 area(const T& polygon) {
Chris@16 1018 typedef typename area_type_by_domain< typename geometry_domain<typename geometry_concept<T>::type>::type,
Chris@16 1019 typename polygon_traits<T>::coordinate_type>::type area_type;
Chris@16 1020 area_type retval = point_sequence_area<typename polygon_traits<T>::iterator_type, area_type>
Chris@16 1021 (begin_points(polygon), end_points(polygon));
Chris@16 1022 if(retval < 0) retval *= -1;
Chris@16 1023 for(typename polygon_with_holes_traits<T>::iterator_holes_type itr =
Chris@16 1024 polygon_with_holes_traits<T>::begin_holes(polygon);
Chris@16 1025 itr != polygon_with_holes_traits<T>::end_holes(polygon); ++itr) {
Chris@16 1026 area_type tmp_area = point_sequence_area
Chris@16 1027 <typename polygon_traits<typename polygon_with_holes_traits<T>::hole_type>::iterator_type, area_type>
Chris@16 1028 (begin_points(*itr), end_points(*itr));
Chris@16 1029 if(tmp_area < 0) tmp_area *= -1;
Chris@16 1030 retval -= tmp_area;
Chris@16 1031 }
Chris@16 1032 return retval;
Chris@16 1033 }
Chris@16 1034
Chris@16 1035 template <typename iT>
Chris@16 1036 bool point_sequence_is_45(iT itr, iT itr_end) {
Chris@16 1037 typedef typename std::iterator_traits<iT>::value_type Point;
Chris@16 1038 typedef typename point_traits<Point>::coordinate_type Unit;
Chris@16 1039 if(itr == itr_end) return true;
Chris@16 1040 Point firstPt = *itr;
Chris@16 1041 Point prevPt = firstPt;
Chris@16 1042 ++itr;
Chris@16 1043 while(itr != itr_end) {
Chris@16 1044 Point pt = *itr;
Chris@16 1045 Unit deltax = x(pt) - x(prevPt);
Chris@16 1046 Unit deltay = y(pt) - y(prevPt);
Chris@16 1047 if(deltax && deltay &&
Chris@16 1048 local_abs(deltax) != local_abs(deltay))
Chris@16 1049 return false;
Chris@16 1050 prevPt = pt;
Chris@16 1051 ++itr;
Chris@16 1052 }
Chris@16 1053 Unit deltax = x(firstPt) - x(prevPt);
Chris@16 1054 Unit deltay = y(firstPt) - y(prevPt);
Chris@16 1055 if(deltax && deltay &&
Chris@16 1056 local_abs(deltax) != local_abs(deltay))
Chris@16 1057 return false;
Chris@16 1058 return true;
Chris@16 1059 }
Chris@16 1060
Chris@16 1061 template <typename polygon_type>
Chris@16 1062 typename enable_if< typename is_polygon_with_holes_type<polygon_type>::type, bool>::type
Chris@16 1063 is_45(const polygon_type& polygon) {
Chris@16 1064 typename polygon_traits<polygon_type>::iterator_type itr = begin_points(polygon), itr_end = end_points(polygon);
Chris@16 1065 if(!point_sequence_is_45(itr, itr_end)) return false;
Chris@16 1066 typename polygon_with_holes_traits<polygon_type>::iterator_holes_type itrh = begin_holes(polygon), itrh_end = end_holes(polygon);
Chris@16 1067 typedef typename polygon_with_holes_traits<polygon_type>::hole_type hole_type;
Chris@16 1068 for(; itrh != itrh_end; ++ itrh) {
Chris@16 1069 typename polygon_traits<hole_type>::iterator_type itr1 = begin_points(polygon), itr1_end = end_points(polygon);
Chris@16 1070 if(!point_sequence_is_45(itr1, itr1_end)) return false;
Chris@16 1071 }
Chris@16 1072 return true;
Chris@16 1073 }
Chris@16 1074
Chris@16 1075 template <typename distance_type, typename iterator_type>
Chris@16 1076 distance_type point_sequence_distance(iterator_type itr, iterator_type itr_end) {
Chris@16 1077 typedef distance_type Unit;
Chris@16 1078 typedef iterator_type iterator;
Chris@16 1079 typedef typename std::iterator_traits<iterator>::value_type point_type;
Chris@16 1080 Unit return_value = Unit(0);
Chris@16 1081 point_type previous_point, first_point;
Chris@16 1082 if(itr == itr_end) return return_value;
Chris@16 1083 previous_point = first_point = *itr;
Chris@16 1084 ++itr;
Chris@16 1085 for( ; itr != itr_end; ++itr) {
Chris@16 1086 point_type current_point = *itr;
Chris@16 1087 return_value += (Unit)euclidean_distance(current_point, previous_point);
Chris@16 1088 previous_point = current_point;
Chris@16 1089 }
Chris@16 1090 return_value += (Unit)euclidean_distance(previous_point, first_point);
Chris@16 1091 return return_value;
Chris@16 1092 }
Chris@16 1093
Chris@16 1094 template <typename T>
Chris@16 1095 typename distance_type_by_domain
Chris@16 1096 <typename geometry_domain<typename geometry_concept<T>::type>::type, typename polygon_traits<T>::coordinate_type>::type
Chris@16 1097 perimeter(const T& polygon,
Chris@16 1098 typename enable_if<
Chris@16 1099 typename is_polygon_with_holes_type<T>::type>::type * = 0
Chris@16 1100 ) {
Chris@16 1101 typedef typename distance_type_by_domain
Chris@16 1102 <typename geometry_domain<typename geometry_concept<T>::type>::type, typename polygon_traits<T>::coordinate_type>::type Unit;
Chris@16 1103 typedef typename polygon_traits<T>::iterator_type iterator;
Chris@16 1104 iterator itr = begin_points(polygon);
Chris@16 1105 iterator itr_end = end_points(polygon);
Chris@16 1106 Unit return_value = point_sequence_distance<Unit, iterator>(itr, itr_end);
Chris@16 1107 for(typename polygon_with_holes_traits<T>::iterator_holes_type itr_holes = begin_holes(polygon);
Chris@16 1108 itr_holes != end_holes(polygon); ++itr_holes) {
Chris@16 1109 typedef typename polygon_traits<typename polygon_with_holes_traits<T>::hole_type>::iterator_type hitertype;
Chris@16 1110 return_value += point_sequence_distance<Unit, hitertype>(begin_points(*itr_holes), end_points(*itr_holes));
Chris@16 1111 }
Chris@16 1112 return return_value;
Chris@16 1113 }
Chris@16 1114
Chris@16 1115 template <typename T>
Chris@16 1116 typename enable_if <typename is_polygon_with_holes_type<T>::type,
Chris@16 1117 direction_1d>::type
Chris@16 1118 winding(const T& polygon) {
Chris@16 1119 winding_direction wd = polygon_traits<T>::winding(polygon);
Chris@16 1120 if(wd != unknown_winding) {
Chris@16 1121 return wd == clockwise_winding ? CLOCKWISE: COUNTERCLOCKWISE;
Chris@16 1122 }
Chris@16 1123 typedef typename area_type_by_domain< typename geometry_domain<typename geometry_concept<T>::type>::type,
Chris@16 1124 typename polygon_traits<T>::coordinate_type>::type area_type;
Chris@16 1125 return point_sequence_area<typename polygon_traits<T>::iterator_type, area_type>(begin_points(polygon), end_points(polygon)) < 0 ?
Chris@16 1126 COUNTERCLOCKWISE : CLOCKWISE;
Chris@16 1127 }
Chris@16 1128
Chris@16 1129 template <typename T, typename input_point_type>
Chris@16 1130 typename enable_if<
Chris@101 1131 typename gtl_and<
Chris@101 1132 typename is_polygon_90_type<T>::type,
Chris@101 1133 typename gtl_same_type<
Chris@101 1134 typename geometry_concept<input_point_type>::type,
Chris@101 1135 point_concept
Chris@101 1136 >::type
Chris@101 1137 >::type,
Chris@101 1138 bool
Chris@101 1139 >::type contains(
Chris@101 1140 const T& polygon,
Chris@101 1141 const input_point_type& point,
Chris@101 1142 bool consider_touch = true) {
Chris@16 1143 typedef T polygon_type;
Chris@16 1144 typedef typename polygon_traits<polygon_type>::coordinate_type coordinate_type;
Chris@16 1145 typedef typename polygon_traits<polygon_type>::iterator_type iterator;
Chris@16 1146 typedef typename std::iterator_traits<iterator>::value_type point_type;
Chris@16 1147 coordinate_type point_x = x(point);
Chris@16 1148 coordinate_type point_y = y(point);
Chris@101 1149 // Check how many intersections has the ray extended from the given
Chris@101 1150 // point in the x-axis negative direction with the polygon edges.
Chris@101 1151 // If the number is odd the point is within the polygon, otherwise not.
Chris@101 1152 // We can safely ignore horizontal edges, however intersections with
Chris@101 1153 // end points of the vertical edges require special handling. We should
Chris@101 1154 // add one intersection in case horizontal edges that extend vertical edge
Chris@101 1155 // point in the same direction.
Chris@101 1156 int num_full_intersections = 0;
Chris@101 1157 int num_half_intersections = 0;
Chris@16 1158 for (iterator iter = begin_points(polygon); iter != end_points(polygon);) {
Chris@16 1159 point_type curr_point = *iter;
Chris@16 1160 ++iter;
Chris@16 1161 point_type next_point = (iter == end_points(polygon)) ? *begin_points(polygon) : *iter;
Chris@16 1162 if (x(curr_point) == x(next_point)) {
Chris@16 1163 if (x(curr_point) > point_x) {
Chris@16 1164 continue;
Chris@16 1165 }
Chris@16 1166 coordinate_type min_y = (std::min)(y(curr_point), y(next_point));
Chris@16 1167 coordinate_type max_y = (std::max)(y(curr_point), y(next_point));
Chris@16 1168 if (point_y > min_y && point_y < max_y) {
Chris@16 1169 if (x(curr_point) == point_x) {
Chris@16 1170 return consider_touch;
Chris@16 1171 }
Chris@101 1172 ++num_full_intersections;
Chris@101 1173 }
Chris@101 1174 if (point_y == min_y || point_y == max_y) {
Chris@101 1175 num_half_intersections += (y(curr_point) < y(next_point) ? 1 : -1);
Chris@16 1176 }
Chris@16 1177 } else {
Chris@16 1178 coordinate_type min_x = (std::min)(x(curr_point), x(next_point));
Chris@16 1179 coordinate_type max_x = (std::max)(x(curr_point), x(next_point));
Chris@16 1180 if (point_x >= min_x && point_x <= max_x) {
Chris@16 1181 if (y(curr_point) == point_y) {
Chris@16 1182 return consider_touch;
Chris@16 1183 }
Chris@16 1184 }
Chris@16 1185 }
Chris@16 1186 }
Chris@101 1187 int total_intersections = num_full_intersections + (num_half_intersections >> 1);
Chris@101 1188 return total_intersections & 1;
Chris@16 1189 }
Chris@16 1190
Chris@16 1191 //TODO: refactor to expose as user APIs
Chris@16 1192 template <typename Unit>
Chris@16 1193 struct edge_utils {
Chris@16 1194 typedef point_data<Unit> Point;
Chris@16 1195 typedef std::pair<Point, Point> half_edge;
Chris@16 1196
Chris@16 1197 class less_point : public std::binary_function<Point, Point, bool> {
Chris@16 1198 public:
Chris@16 1199 inline less_point() {}
Chris@16 1200 inline bool operator () (const Point& pt1, const Point& pt2) const {
Chris@16 1201 if(pt1.get(HORIZONTAL) < pt2.get(HORIZONTAL)) return true;
Chris@16 1202 if(pt1.get(HORIZONTAL) == pt2.get(HORIZONTAL)) {
Chris@16 1203 if(pt1.get(VERTICAL) < pt2.get(VERTICAL)) return true;
Chris@16 1204 }
Chris@16 1205 return false;
Chris@16 1206 }
Chris@16 1207 };
Chris@16 1208
Chris@16 1209 static inline bool between(Point pt, Point pt1, Point pt2) {
Chris@16 1210 less_point lp;
Chris@16 1211 if(lp(pt1, pt2))
Chris@16 1212 return lp(pt, pt2) && lp(pt1, pt);
Chris@16 1213 return lp(pt, pt1) && lp(pt2, pt);
Chris@16 1214 }
Chris@16 1215
Chris@16 1216 template <typename area_type>
Chris@16 1217 static inline bool equal_slope(area_type dx1, area_type dy1, area_type dx2, area_type dy2) {
Chris@16 1218 typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type;
Chris@16 1219 unsigned_product_type cross_1 = (unsigned_product_type)(dx2 < 0 ? -dx2 :dx2) * (unsigned_product_type)(dy1 < 0 ? -dy1 : dy1);
Chris@16 1220 unsigned_product_type cross_2 = (unsigned_product_type)(dx1 < 0 ? -dx1 :dx1) * (unsigned_product_type)(dy2 < 0 ? -dy2 : dy2);
Chris@16 1221 int dx1_sign = dx1 < 0 ? -1 : 1;
Chris@16 1222 int dx2_sign = dx2 < 0 ? -1 : 1;
Chris@16 1223 int dy1_sign = dy1 < 0 ? -1 : 1;
Chris@16 1224 int dy2_sign = dy2 < 0 ? -1 : 1;
Chris@16 1225 int cross_1_sign = dx2_sign * dy1_sign;
Chris@16 1226 int cross_2_sign = dx1_sign * dy2_sign;
Chris@16 1227 return cross_1 == cross_2 && (cross_1_sign == cross_2_sign || cross_1 == 0);
Chris@16 1228 }
Chris@16 1229
Chris@16 1230 static inline bool equal_slope(const Unit& x, const Unit& y,
Chris@16 1231 const Point& pt1, const Point& pt2) {
Chris@16 1232 const Point* pts[2] = {&pt1, &pt2};
Chris@16 1233 typedef typename coordinate_traits<Unit>::manhattan_area_type at;
Chris@16 1234 at dy2 = (at)pts[1]->get(VERTICAL) - (at)y;
Chris@16 1235 at dy1 = (at)pts[0]->get(VERTICAL) - (at)y;
Chris@16 1236 at dx2 = (at)pts[1]->get(HORIZONTAL) - (at)x;
Chris@16 1237 at dx1 = (at)pts[0]->get(HORIZONTAL) - (at)x;
Chris@16 1238 return equal_slope(dx1, dy1, dx2, dy2);
Chris@16 1239 }
Chris@16 1240
Chris@16 1241 template <typename area_type>
Chris@16 1242 static inline bool less_slope(area_type dx1, area_type dy1, area_type dx2, area_type dy2) {
Chris@16 1243 //reflext x and y slopes to right hand side half plane
Chris@16 1244 if(dx1 < 0) {
Chris@16 1245 dy1 *= -1;
Chris@16 1246 dx1 *= -1;
Chris@16 1247 } else if(dx1 == 0) {
Chris@16 1248 //if the first slope is vertical the first cannot be less
Chris@16 1249 return false;
Chris@16 1250 }
Chris@16 1251 if(dx2 < 0) {
Chris@16 1252 dy2 *= -1;
Chris@16 1253 dx2 *= -1;
Chris@16 1254 } else if(dx2 == 0) {
Chris@16 1255 //if the second slope is vertical the first is always less unless it is also vertical, in which case they are equal
Chris@16 1256 return dx1 != 0;
Chris@16 1257 }
Chris@16 1258 typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type;
Chris@16 1259 unsigned_product_type cross_1 = (unsigned_product_type)(dx2 < 0 ? -dx2 :dx2) * (unsigned_product_type)(dy1 < 0 ? -dy1 : dy1);
Chris@16 1260 unsigned_product_type cross_2 = (unsigned_product_type)(dx1 < 0 ? -dx1 :dx1) * (unsigned_product_type)(dy2 < 0 ? -dy2 : dy2);
Chris@16 1261 int dx1_sign = dx1 < 0 ? -1 : 1;
Chris@16 1262 int dx2_sign = dx2 < 0 ? -1 : 1;
Chris@16 1263 int dy1_sign = dy1 < 0 ? -1 : 1;
Chris@16 1264 int dy2_sign = dy2 < 0 ? -1 : 1;
Chris@16 1265 int cross_1_sign = dx2_sign * dy1_sign;
Chris@16 1266 int cross_2_sign = dx1_sign * dy2_sign;
Chris@16 1267 if(cross_1_sign < cross_2_sign) return true;
Chris@16 1268 if(cross_2_sign < cross_1_sign) return false;
Chris@16 1269 if(cross_1_sign == -1) return cross_2 < cross_1;
Chris@16 1270 return cross_1 < cross_2;
Chris@16 1271 }
Chris@16 1272
Chris@16 1273 static inline bool less_slope(const Unit& x, const Unit& y,
Chris@16 1274 const Point& pt1, const Point& pt2) {
Chris@16 1275 const Point* pts[2] = {&pt1, &pt2};
Chris@16 1276 //compute y value on edge from pt_ to pts[1] at the x value of pts[0]
Chris@16 1277 typedef typename coordinate_traits<Unit>::manhattan_area_type at;
Chris@16 1278 at dy2 = (at)pts[1]->get(VERTICAL) - (at)y;
Chris@16 1279 at dy1 = (at)pts[0]->get(VERTICAL) - (at)y;
Chris@16 1280 at dx2 = (at)pts[1]->get(HORIZONTAL) - (at)x;
Chris@16 1281 at dx1 = (at)pts[0]->get(HORIZONTAL) - (at)x;
Chris@16 1282 return less_slope(dx1, dy1, dx2, dy2);
Chris@16 1283 }
Chris@16 1284
Chris@16 1285 //return -1 below, 0 on and 1 above line
Chris@16 1286 //assumes point is on x interval of segment
Chris@16 1287 static inline int on_above_or_below(Point pt, const half_edge& he) {
Chris@16 1288 if(pt == he.first || pt == he.second) return 0;
Chris@16 1289 if(equal_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), he.first, he.second)) return 0;
Chris@16 1290 bool less_result = less_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), he.first, he.second);
Chris@16 1291 int retval = less_result ? -1 : 1;
Chris@16 1292 less_point lp;
Chris@16 1293 if(lp(he.second, he.first)) retval *= -1;
Chris@16 1294 if(!between(pt, he.first, he.second)) retval *= -1;
Chris@16 1295 return retval;
Chris@16 1296 }
Chris@16 1297 };
Chris@16 1298
Chris@16 1299 template <typename T, typename input_point_type>
Chris@16 1300 typename enable_if<
Chris@16 1301 typename gtl_and< typename is_any_mutable_polygon_with_holes_type<T>::type,
Chris@16 1302 typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type,
Chris@16 1303 bool>::type
Chris@16 1304 contains(const T& polygon, const input_point_type& point, bool consider_touch = true) {
Chris@16 1305 typedef typename polygon_with_holes_traits<T>::iterator_holes_type holes_iterator;
Chris@16 1306 bool isInside = contains( view_as< typename polygon_from_polygon_with_holes_type<
Chris@16 1307 typename geometry_concept<T>::type>::type>( polygon ), point, consider_touch );
Chris@16 1308 if(!isInside) return false; //no need to check holes
Chris@16 1309 holes_iterator itH = begin_holes( polygon );
Chris@16 1310 while( itH != end_holes( polygon ) ) {
Chris@16 1311 if( contains( *itH, point, !consider_touch ) ) {
Chris@16 1312 isInside = false;
Chris@16 1313 break;
Chris@16 1314 }
Chris@16 1315 ++itH;
Chris@16 1316 }
Chris@16 1317 return isInside;
Chris@16 1318 }
Chris@16 1319
Chris@16 1320 template <typename T, typename input_point_type>
Chris@16 1321 typename enable_if<
Chris@16 1322 typename gtl_and_3<
Chris@16 1323 typename is_polygon_type<T>::type,
Chris@16 1324 typename gtl_different_type<typename geometry_domain<typename geometry_concept<T>::type>::type, manhattan_domain>::type,
Chris@16 1325 typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type,
Chris@16 1326 bool>::type
Chris@16 1327 contains(const T& polygon, const input_point_type& point, bool consider_touch = true) {
Chris@16 1328 typedef typename point_traits<input_point_type>::coordinate_type Unit;
Chris@16 1329 typedef point_data<Unit> Point;
Chris@16 1330 typedef std::pair<Point, Point> half_edge;
Chris@16 1331 typedef typename polygon_traits<T>::iterator_type iterator;
Chris@16 1332 iterator itr = begin_points(polygon);
Chris@16 1333 iterator itrEnd = end_points(polygon);
Chris@16 1334 half_edge he;
Chris@16 1335 if(itr == itrEnd) return false;
Chris@16 1336 assign(he.first, *itr);
Chris@16 1337 Point firstPt;
Chris@16 1338 assign(firstPt, *itr);
Chris@16 1339 ++itr;
Chris@16 1340 if(itr == itrEnd) return false;
Chris@16 1341 bool done = false;
Chris@16 1342 int above = 0;
Chris@16 1343 while(!done) {
Chris@16 1344 Point currentPt;
Chris@16 1345 if(itr == itrEnd) {
Chris@16 1346 done = true;
Chris@16 1347 currentPt = firstPt;
Chris@16 1348 } else {
Chris@16 1349 assign(currentPt, *itr);
Chris@16 1350 ++itr;
Chris@16 1351 }
Chris@16 1352 if(currentPt == he.first) {
Chris@16 1353 continue;
Chris@16 1354 } else {
Chris@16 1355 he.second = currentPt;
Chris@16 1356 if(equivalence(point, currentPt)) return consider_touch;
Chris@16 1357 Unit xmin = (std::min)(x(he.first), x(he.second));
Chris@16 1358 Unit xmax = (std::max)(x(he.first), x(he.second));
Chris@16 1359 if(x(point) >= xmin && x(point) < xmax) { //double counts if <= xmax
Chris@16 1360 Point tmppt;
Chris@16 1361 assign(tmppt, point);
Chris@16 1362 int oabedge = edge_utils<Unit>::on_above_or_below(tmppt, he);
Chris@16 1363 if(oabedge == 0) return consider_touch;
Chris@16 1364 if(oabedge == 1) ++above;
Chris@16 1365 } else if(x(point) == xmax) {
Chris@16 1366 if(x(point) == xmin) {
Chris@16 1367 Unit ymin = (std::min)(y(he.first), y(he.second));
Chris@16 1368 Unit ymax = (std::max)(y(he.first), y(he.second));
Chris@16 1369 Unit ypt = y(point);
Chris@16 1370 if(ypt <= ymax && ypt >= ymin)
Chris@16 1371 return consider_touch;
Chris@16 1372 } else {
Chris@16 1373 Point tmppt;
Chris@16 1374 assign(tmppt, point);
Chris@16 1375 if( edge_utils<Unit>::on_above_or_below(tmppt, he) == 0 ) {
Chris@16 1376 return consider_touch;
Chris@16 1377 }
Chris@16 1378 }
Chris@16 1379 }
Chris@16 1380 }
Chris@16 1381 he.first = he.second;
Chris@16 1382 }
Chris@16 1383 return above % 2 != 0; //if the point is above an odd number of edges is must be inside polygon
Chris@16 1384 }
Chris@16 1385
Chris@16 1386 /*
Chris@16 1387 template <typename T, typename input_point_type>
Chris@16 1388 typename enable_if<
Chris@16 1389 typename gtl_and_3<
Chris@16 1390 typename is_polygon_with_holes_type<T>::type,
Chris@16 1391 typename gtl_different_type<typename geometry_domain<typename geometry_concept<T>::type>::type, manhattan_domain>::type,
Chris@16 1392 typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type,
Chris@16 1393 bool>::type
Chris@16 1394 contains(const T& polygon, const input_point_type& point, bool consider_touch = true) {
Chris@16 1395 typedef typename point_traits<input_point_type>::coordinate_type Unit;
Chris@16 1396 typedef point_data<Unit> Point;
Chris@16 1397 typedef std::pair<Point, Point> half_edge;
Chris@16 1398 typedef typename polygon_traits<T>::iterator_type iterator;
Chris@16 1399 iterator itr = begin_points(polygon);
Chris@16 1400 iterator itrEnd = end_points(polygon);
Chris@16 1401 half_edge he;
Chris@16 1402 if(itr == itrEnd) return false;
Chris@16 1403 assign(he.first, *itr);
Chris@16 1404 Point firstPt;
Chris@16 1405 assign(firstPt, *itr);
Chris@16 1406 ++itr;
Chris@16 1407 if(itr == itrEnd) return false;
Chris@16 1408 bool done = false;
Chris@16 1409 int above = 0;
Chris@16 1410 while(!done) {
Chris@16 1411 Point currentPt;
Chris@16 1412 if(itr == itrEnd) {
Chris@16 1413 done = true;
Chris@16 1414 currentPt = firstPt;
Chris@16 1415 } else {
Chris@16 1416 assign(currentPt, *itr);
Chris@16 1417 ++itr;
Chris@16 1418 }
Chris@16 1419 if(currentPt == he.first) {
Chris@16 1420 continue;
Chris@16 1421 } else {
Chris@16 1422 he.second = currentPt;
Chris@16 1423 if(equivalence(point, currentPt)) return consider_touch;
Chris@16 1424 Unit xmin = (std::min)(x(he.first), x(he.second));
Chris@16 1425 Unit xmax = (std::max)(x(he.first), x(he.second));
Chris@16 1426 if(x(point) >= xmin && x(point) < xmax) { //double counts if <= xmax
Chris@16 1427 Point tmppt;
Chris@16 1428 assign(tmppt, point);
Chris@16 1429 int oabedge = edge_utils<Unit>::on_above_or_below(tmppt, he);
Chris@16 1430 if(oabedge == 0) return consider_touch;
Chris@16 1431 if(oabedge == 1) ++above;
Chris@16 1432 }
Chris@16 1433 }
Chris@16 1434 he.first = he.second;
Chris@16 1435 }
Chris@16 1436 return above % 2 != 0; //if the point is above an odd number of edges is must be inside polygon
Chris@16 1437 }
Chris@16 1438 */
Chris@16 1439
Chris@16 1440 template <typename T1, typename T2>
Chris@16 1441 typename enable_if<
Chris@16 1442 typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<T1>::type>::type,
Chris@16 1443 typename is_polygon_with_holes_type<T2>::type>::type,
Chris@16 1444 bool>::type
Chris@16 1445 extents(T1& bounding_box, const T2& polygon) {
Chris@16 1446 typedef typename polygon_traits<T2>::iterator_type iterator;
Chris@16 1447 bool first_iteration = true;
Chris@16 1448 iterator itr_end = end_points(polygon);
Chris@16 1449 for(iterator itr = begin_points(polygon); itr != itr_end; ++itr) {
Chris@16 1450 if(first_iteration) {
Chris@16 1451 set_points(bounding_box, *itr, *itr);
Chris@16 1452 first_iteration = false;
Chris@16 1453 } else {
Chris@16 1454 encompass(bounding_box, *itr);
Chris@16 1455 }
Chris@16 1456 }
Chris@16 1457 if(first_iteration) return false;
Chris@16 1458 return true;
Chris@16 1459 }
Chris@16 1460
Chris@101 1461 template <typename T1, typename T2>
Chris@101 1462 typename enable_if<
Chris@101 1463 typename gtl_and< typename is_mutable_point_concept<typename geometry_concept<T1>::type>::type,
Chris@101 1464 typename is_polygon_with_holes_type<T2>::type>::type,
Chris@101 1465 bool>::type
Chris@101 1466 center(T1& center_point, const T2& polygon) {
Chris@101 1467 typedef typename polygon_traits<T2>::coordinate_type coordinate_type;
Chris@101 1468 rectangle_data<coordinate_type> bbox;
Chris@101 1469 extents(bbox, polygon);
Chris@101 1470 return center(center_point, bbox);
Chris@101 1471 }
Chris@101 1472
Chris@16 1473 template <class T>
Chris@16 1474 template <class T2>
Chris@16 1475 polygon_90_data<T>& polygon_90_data<T>::operator=(const T2& rvalue) {
Chris@16 1476 assign(*this, rvalue);
Chris@16 1477 return *this;
Chris@16 1478 }
Chris@16 1479
Chris@16 1480 template <class T>
Chris@16 1481 template <class T2>
Chris@16 1482 polygon_45_data<T>& polygon_45_data<T>::operator=(const T2& rvalue) {
Chris@16 1483 assign(*this, rvalue);
Chris@16 1484 return *this;
Chris@16 1485 }
Chris@16 1486
Chris@16 1487 template <class T>
Chris@16 1488 template <class T2>
Chris@16 1489 polygon_data<T>& polygon_data<T>::operator=(const T2& rvalue) {
Chris@16 1490 assign(*this, rvalue);
Chris@16 1491 return *this;
Chris@16 1492 }
Chris@16 1493
Chris@16 1494 template <class T>
Chris@16 1495 template <class T2>
Chris@16 1496 polygon_90_with_holes_data<T>& polygon_90_with_holes_data<T>::operator=(const T2& rvalue) {
Chris@16 1497 assign(*this, rvalue);
Chris@16 1498 return *this;
Chris@16 1499 }
Chris@16 1500
Chris@16 1501 template <class T>
Chris@16 1502 template <class T2>
Chris@16 1503 polygon_45_with_holes_data<T>& polygon_45_with_holes_data<T>::operator=(const T2& rvalue) {
Chris@16 1504 assign(*this, rvalue);
Chris@16 1505 return *this;
Chris@16 1506 }
Chris@16 1507
Chris@16 1508 template <class T>
Chris@16 1509 template <class T2>
Chris@16 1510 polygon_with_holes_data<T>& polygon_with_holes_data<T>::operator=(const T2& rvalue) {
Chris@16 1511 assign(*this, rvalue);
Chris@16 1512 return *this;
Chris@16 1513 }
Chris@16 1514
Chris@16 1515 template <typename T>
Chris@16 1516 struct geometry_concept<polygon_data<T> > {
Chris@16 1517 typedef polygon_concept type;
Chris@16 1518 };
Chris@16 1519 template <typename T>
Chris@16 1520 struct geometry_concept<polygon_45_data<T> > {
Chris@16 1521 typedef polygon_45_concept type;
Chris@16 1522 };
Chris@16 1523 template <typename T>
Chris@16 1524 struct geometry_concept<polygon_90_data<T> > {
Chris@16 1525 typedef polygon_90_concept type;
Chris@16 1526 };
Chris@16 1527 template <typename T>
Chris@16 1528 struct geometry_concept<polygon_with_holes_data<T> > {
Chris@16 1529 typedef polygon_with_holes_concept type;
Chris@16 1530 };
Chris@16 1531 template <typename T>
Chris@16 1532 struct geometry_concept<polygon_45_with_holes_data<T> > {
Chris@16 1533 typedef polygon_45_with_holes_concept type;
Chris@16 1534 };
Chris@16 1535 template <typename T>
Chris@16 1536 struct geometry_concept<polygon_90_with_holes_data<T> > {
Chris@16 1537 typedef polygon_90_with_holes_concept type;
Chris@16 1538 };
Chris@16 1539
Chris@16 1540 // template <typename T> struct polygon_with_holes_traits<polygon_90_data<T> > {
Chris@16 1541 // typedef polygon_90_data<T> hole_type;
Chris@16 1542 // typedef const hole_type* iterator_holes_type;
Chris@16 1543 // static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; }
Chris@16 1544 // static inline iterator_holes_type end_holes(const hole_type& t) { return &t; }
Chris@16 1545 // static inline std::size_t size_holes(const hole_type& t) { return 0; }
Chris@16 1546 // };
Chris@16 1547 // template <typename T> struct polygon_with_holes_traits<polygon_45_data<T> > {
Chris@16 1548 // typedef polygon_45_data<T> hole_type;
Chris@16 1549 // typedef const hole_type* iterator_holes_type;
Chris@16 1550 // static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; }
Chris@16 1551 // static inline iterator_holes_type end_holes(const hole_type& t) { return &t; }
Chris@16 1552 // static inline std::size_t size_holes(const hole_type& t) { return 0; }
Chris@16 1553 // };
Chris@16 1554 // template <typename T> struct polygon_with_holes_traits<polygon_data<T> > {
Chris@16 1555 // typedef polygon_data<T> hole_type;
Chris@16 1556 // typedef const hole_type* iterator_holes_type;
Chris@16 1557 // static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; }
Chris@16 1558 // static inline iterator_holes_type end_holes(const hole_type& t) { return &t; }
Chris@16 1559 // static inline std::size_t size_holes(const hole_type& t) { return 0; }
Chris@16 1560 // };
Chris@16 1561 template <typename T> struct get_void {};
Chris@16 1562 template <> struct get_void<gtl_yes> { typedef void type; };
Chris@16 1563
Chris@16 1564 template <typename T> struct polygon_with_holes_traits<
Chris@16 1565 T, typename get_void<typename is_any_mutable_polygon_without_holes_type<T>::type>::type > {
Chris@16 1566 typedef T hole_type;
Chris@16 1567 typedef const hole_type* iterator_holes_type;
Chris@16 1568 static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; }
Chris@16 1569 static inline iterator_holes_type end_holes(const hole_type& t) { return &t; }
Chris@16 1570 static inline std::size_t size_holes(const hole_type& t) { return 0; }
Chris@16 1571 };
Chris@16 1572
Chris@16 1573 template <typename T>
Chris@16 1574 struct view_of<rectangle_concept, T> {
Chris@16 1575 typedef typename polygon_traits<T>::coordinate_type coordinate_type;
Chris@16 1576 typedef interval_data<coordinate_type> interval_type;
Chris@16 1577 rectangle_data<coordinate_type> rect;
Chris@16 1578 view_of(const T& obj) : rect() {
Chris@16 1579 point_data<coordinate_type> pts[2];
Chris@16 1580 typename polygon_traits<T>::iterator_type itr =
Chris@16 1581 begin_points(obj), itre = end_points(obj);
Chris@16 1582 if(itr == itre) return;
Chris@16 1583 assign(pts[0], *itr);
Chris@16 1584 ++itr;
Chris@16 1585 if(itr == itre) return;
Chris@16 1586 ++itr;
Chris@16 1587 if(itr == itre) return;
Chris@16 1588 assign(pts[1], *itr);
Chris@16 1589 set_points(rect, pts[0], pts[1]);
Chris@16 1590 }
Chris@16 1591 inline interval_type get(orientation_2d orient) const {
Chris@16 1592 return rect.get(orient); }
Chris@16 1593 };
Chris@16 1594
Chris@16 1595 template <typename T>
Chris@16 1596 struct geometry_concept<view_of<rectangle_concept, T> > {
Chris@16 1597 typedef rectangle_concept type;
Chris@16 1598 };
Chris@16 1599
Chris@16 1600 template <typename T>
Chris@16 1601 struct view_of<polygon_45_concept, T> {
Chris@16 1602 const T* t;
Chris@16 1603 view_of(const T& obj) : t(&obj) {}
Chris@16 1604 typedef typename polygon_traits<T>::coordinate_type coordinate_type;
Chris@16 1605 typedef typename polygon_traits<T>::iterator_type iterator_type;
Chris@16 1606 typedef typename polygon_traits<T>::point_type point_type;
Chris@16 1607
Chris@16 1608 /// Get the begin iterator
Chris@16 1609 inline iterator_type begin() const {
Chris@16 1610 return polygon_traits<T>::begin_points(*t);
Chris@16 1611 }
Chris@16 1612
Chris@16 1613 /// Get the end iterator
Chris@16 1614 inline iterator_type end() const {
Chris@16 1615 return polygon_traits<T>::end_points(*t);
Chris@16 1616 }
Chris@16 1617
Chris@16 1618 /// Get the number of sides of the polygon
Chris@16 1619 inline std::size_t size() const {
Chris@16 1620 return polygon_traits<T>::size(*t);
Chris@16 1621 }
Chris@16 1622
Chris@16 1623 /// Get the winding direction of the polygon
Chris@16 1624 inline winding_direction winding() const {
Chris@16 1625 return polygon_traits<T>::winding(*t);
Chris@16 1626 }
Chris@16 1627 };
Chris@16 1628
Chris@16 1629 template <typename T>
Chris@16 1630 struct geometry_concept<view_of<polygon_45_concept, T> > {
Chris@16 1631 typedef polygon_45_concept type;
Chris@16 1632 };
Chris@16 1633
Chris@16 1634 template <typename T>
Chris@16 1635 struct view_of<polygon_90_concept, T> {
Chris@16 1636 const T* t;
Chris@16 1637 view_of(const T& obj) : t(&obj) {}
Chris@16 1638 typedef typename polygon_traits<T>::coordinate_type coordinate_type;
Chris@16 1639 typedef typename polygon_traits<T>::iterator_type iterator_type;
Chris@16 1640 typedef typename polygon_traits<T>::point_type point_type;
Chris@16 1641 typedef iterator_points_to_compact<iterator_type, point_type> compact_iterator_type;
Chris@16 1642
Chris@16 1643 /// Get the begin iterator
Chris@16 1644 inline compact_iterator_type begin_compact() const {
Chris@16 1645 return compact_iterator_type(polygon_traits<T>::begin_points(*t),
Chris@16 1646 polygon_traits<T>::end_points(*t));
Chris@16 1647 }
Chris@16 1648
Chris@16 1649 /// Get the end iterator
Chris@16 1650 inline compact_iterator_type end_compact() const {
Chris@16 1651 return compact_iterator_type(polygon_traits<T>::end_points(*t),
Chris@16 1652 polygon_traits<T>::end_points(*t));
Chris@16 1653 }
Chris@16 1654
Chris@16 1655 /// Get the number of sides of the polygon
Chris@16 1656 inline std::size_t size() const {
Chris@16 1657 return polygon_traits<T>::size(*t);
Chris@16 1658 }
Chris@16 1659
Chris@16 1660 /// Get the winding direction of the polygon
Chris@16 1661 inline winding_direction winding() const {
Chris@16 1662 return polygon_traits<T>::winding(*t);
Chris@16 1663 }
Chris@16 1664 };
Chris@16 1665
Chris@16 1666 template <typename T>
Chris@16 1667 struct geometry_concept<view_of<polygon_90_concept, T> > {
Chris@16 1668 typedef polygon_90_concept type;
Chris@16 1669 };
Chris@16 1670
Chris@16 1671 template <typename T>
Chris@16 1672 struct view_of<polygon_45_with_holes_concept, T> {
Chris@16 1673 const T* t;
Chris@16 1674 view_of(const T& obj) : t(&obj) {}
Chris@16 1675 typedef typename polygon_traits<T>::coordinate_type coordinate_type;
Chris@16 1676 typedef typename polygon_traits<T>::iterator_type iterator_type;
Chris@16 1677 typedef typename polygon_traits<T>::point_type point_type;
Chris@16 1678 typedef view_of<polygon_45_concept, typename polygon_with_holes_traits<T>::hole_type> hole_type;
Chris@16 1679 struct iterator_holes_type {
Chris@16 1680 typedef std::forward_iterator_tag iterator_category;
Chris@16 1681 typedef hole_type value_type;
Chris@16 1682 typedef std::ptrdiff_t difference_type;
Chris@16 1683 typedef const hole_type* pointer; //immutable
Chris@16 1684 typedef const hole_type& reference; //immutable
Chris@16 1685 typedef typename polygon_with_holes_traits<T>::iterator_holes_type iht;
Chris@16 1686 iht internal_itr;
Chris@16 1687 iterator_holes_type() : internal_itr() {}
Chris@16 1688 iterator_holes_type(iht iht_in) : internal_itr(iht_in) {}
Chris@16 1689 inline iterator_holes_type& operator++() {
Chris@16 1690 ++internal_itr;
Chris@16 1691 return *this;
Chris@16 1692 }
Chris@16 1693 inline const iterator_holes_type operator++(int) {
Chris@16 1694 iterator_holes_type tmp(*this);
Chris@16 1695 ++(*this);
Chris@16 1696 return tmp;
Chris@16 1697 }
Chris@16 1698 inline bool operator==(const iterator_holes_type& that) const {
Chris@16 1699 return (internal_itr == that.internal_itr);
Chris@16 1700 }
Chris@16 1701 inline bool operator!=(const iterator_holes_type& that) const {
Chris@16 1702 return (internal_itr != that.internal_itr);
Chris@16 1703 }
Chris@16 1704 inline value_type operator*() const {
Chris@16 1705 return view_as<polygon_45_concept>(*internal_itr);
Chris@16 1706 }
Chris@16 1707 };
Chris@16 1708
Chris@16 1709 /// Get the begin iterator
Chris@16 1710 inline iterator_type begin() const {
Chris@16 1711 return polygon_traits<T>::begin_points(*t);
Chris@16 1712 }
Chris@16 1713
Chris@16 1714 /// Get the end iterator
Chris@16 1715 inline iterator_type end() const {
Chris@16 1716 return polygon_traits<T>::end_points(*t);
Chris@16 1717 }
Chris@16 1718
Chris@16 1719 /// Get the number of sides of the polygon
Chris@16 1720 inline std::size_t size() const {
Chris@16 1721 return polygon_traits<T>::size(*t);
Chris@16 1722 }
Chris@16 1723
Chris@16 1724 /// Get the winding direction of the polygon
Chris@16 1725 inline winding_direction winding() const {
Chris@16 1726 return polygon_traits<T>::winding(*t);
Chris@16 1727 }
Chris@16 1728
Chris@16 1729 /// Get the begin iterator
Chris@16 1730 inline iterator_holes_type begin_holes() const {
Chris@16 1731 return polygon_with_holes_traits<T>::begin_holes(*t);
Chris@16 1732 }
Chris@16 1733
Chris@16 1734 /// Get the end iterator
Chris@16 1735 inline iterator_holes_type end_holes() const {
Chris@16 1736 return polygon_with_holes_traits<T>::end_holes(*t);
Chris@16 1737 }
Chris@16 1738
Chris@16 1739 /// Get the number of sides of the polygon
Chris@16 1740 inline std::size_t size_holes() const {
Chris@16 1741 return polygon_with_holes_traits<T>::size_holes(*t);
Chris@16 1742 }
Chris@16 1743
Chris@16 1744 };
Chris@16 1745
Chris@16 1746 template <typename T>
Chris@16 1747 struct geometry_concept<view_of<polygon_45_with_holes_concept, T> > {
Chris@16 1748 typedef polygon_45_with_holes_concept type;
Chris@16 1749 };
Chris@16 1750
Chris@16 1751 template <typename T>
Chris@16 1752 struct view_of<polygon_90_with_holes_concept, T> {
Chris@16 1753 const T* t;
Chris@16 1754 view_of(const T& obj) : t(&obj) {}
Chris@16 1755 typedef typename polygon_traits<T>::coordinate_type coordinate_type;
Chris@16 1756 typedef typename polygon_traits<T>::iterator_type iterator_type;
Chris@16 1757 typedef typename polygon_traits<T>::point_type point_type;
Chris@16 1758 typedef iterator_points_to_compact<iterator_type, point_type> compact_iterator_type;
Chris@16 1759 typedef view_of<polygon_90_concept, typename polygon_with_holes_traits<T>::hole_type> hole_type;
Chris@16 1760 struct iterator_holes_type {
Chris@16 1761 typedef std::forward_iterator_tag iterator_category;
Chris@16 1762 typedef hole_type value_type;
Chris@16 1763 typedef std::ptrdiff_t difference_type;
Chris@16 1764 typedef const hole_type* pointer; //immutable
Chris@16 1765 typedef const hole_type& reference; //immutable
Chris@16 1766 typedef typename polygon_with_holes_traits<T>::iterator_holes_type iht;
Chris@16 1767 iht internal_itr;
Chris@16 1768 iterator_holes_type() : internal_itr() {}
Chris@16 1769 iterator_holes_type(iht iht_in) : internal_itr(iht_in) {}
Chris@16 1770 inline iterator_holes_type& operator++() {
Chris@16 1771 ++internal_itr;
Chris@16 1772 return *this;
Chris@16 1773 }
Chris@16 1774 inline const iterator_holes_type operator++(int) {
Chris@16 1775 iterator_holes_type tmp(*this);
Chris@16 1776 ++(*this);
Chris@16 1777 return tmp;
Chris@16 1778 }
Chris@16 1779 inline bool operator==(const iterator_holes_type& that) const {
Chris@16 1780 return (internal_itr == that.internal_itr);
Chris@16 1781 }
Chris@16 1782 inline bool operator!=(const iterator_holes_type& that) const {
Chris@16 1783 return (internal_itr != that.internal_itr);
Chris@16 1784 }
Chris@16 1785 inline value_type operator*() const {
Chris@16 1786 return view_as<polygon_90_concept>(*internal_itr);
Chris@16 1787 }
Chris@16 1788 };
Chris@16 1789
Chris@16 1790 /// Get the begin iterator
Chris@16 1791 inline compact_iterator_type begin_compact() const {
Chris@16 1792 return compact_iterator_type(polygon_traits<T>::begin_points(*t),
Chris@16 1793 polygon_traits<T>::end_points(*t));
Chris@16 1794 }
Chris@16 1795
Chris@16 1796 /// Get the end iterator
Chris@16 1797 inline compact_iterator_type end_compact() const {
Chris@16 1798 return compact_iterator_type(polygon_traits<T>::end_points(*t),
Chris@16 1799 polygon_traits<T>::end_points(*t));
Chris@16 1800 }
Chris@16 1801
Chris@16 1802 /// Get the number of sides of the polygon
Chris@16 1803 inline std::size_t size() const {
Chris@16 1804 return polygon_traits<T>::size(*t);
Chris@16 1805 }
Chris@16 1806
Chris@16 1807 /// Get the winding direction of the polygon
Chris@16 1808 inline winding_direction winding() const {
Chris@16 1809 return polygon_traits<T>::winding(*t);
Chris@16 1810 }
Chris@16 1811
Chris@16 1812 /// Get the begin iterator
Chris@16 1813 inline iterator_holes_type begin_holes() const {
Chris@16 1814 return polygon_with_holes_traits<T>::begin_holes(*t);
Chris@16 1815 }
Chris@16 1816
Chris@16 1817 /// Get the end iterator
Chris@16 1818 inline iterator_holes_type end_holes() const {
Chris@16 1819 return polygon_with_holes_traits<T>::end_holes(*t);
Chris@16 1820 }
Chris@16 1821
Chris@16 1822 /// Get the number of sides of the polygon
Chris@16 1823 inline std::size_t size_holes() const {
Chris@16 1824 return polygon_with_holes_traits<T>::size_holes(*t);
Chris@16 1825 }
Chris@16 1826
Chris@16 1827 };
Chris@16 1828
Chris@16 1829 template <typename T>
Chris@16 1830 struct geometry_concept<view_of<polygon_90_with_holes_concept, T> > {
Chris@16 1831 typedef polygon_90_with_holes_concept type;
Chris@16 1832 };
Chris@16 1833
Chris@16 1834 template <typename T>
Chris@16 1835 struct view_of<polygon_concept, T> {
Chris@16 1836 const T* t;
Chris@16 1837 view_of(const T& obj) : t(&obj) {}
Chris@16 1838 typedef typename polygon_traits<T>::coordinate_type coordinate_type;
Chris@16 1839 typedef typename polygon_traits<T>::iterator_type iterator_type;
Chris@16 1840 typedef typename polygon_traits<T>::point_type point_type;
Chris@16 1841
Chris@16 1842 /// Get the begin iterator
Chris@16 1843 inline iterator_type begin() const {
Chris@16 1844 return polygon_traits<T>::begin_points(*t);
Chris@16 1845 }
Chris@16 1846
Chris@16 1847 /// Get the end iterator
Chris@16 1848 inline iterator_type end() const {
Chris@16 1849 return polygon_traits<T>::end_points(*t);
Chris@16 1850 }
Chris@16 1851
Chris@16 1852 /// Get the number of sides of the polygon
Chris@16 1853 inline std::size_t size() const {
Chris@16 1854 return polygon_traits<T>::size(*t);
Chris@16 1855 }
Chris@16 1856
Chris@16 1857 /// Get the winding direction of the polygon
Chris@16 1858 inline winding_direction winding() const {
Chris@16 1859 return polygon_traits<T>::winding(*t);
Chris@16 1860 }
Chris@16 1861 };
Chris@16 1862
Chris@16 1863 template <typename T>
Chris@16 1864 struct geometry_concept<view_of<polygon_concept, T> > {
Chris@16 1865 typedef polygon_concept type;
Chris@16 1866 };
Chris@16 1867 }
Chris@16 1868 }
Chris@16 1869
Chris@16 1870 #endif