1 /* 2 Copyright 2008 Intel Corporation 3 4 Use, modification and distribution are subject to the Boost Software License, 5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 6 http://www.boost.org/LICENSE_1_0.txt). 7 */ 8 #ifndef BOOST_POLYGON_RECTANGLE_CONCEPT_HPP 9 #define BOOST_POLYGON_RECTANGLE_CONCEPT_HPP 10 11 #include "isotropy.hpp" 12 13 //point 14 #include "point_data.hpp" 15 #include "point_traits.hpp" 16 #include "point_concept.hpp" 17 18 //interval 19 #include "interval_data.hpp" 20 #include "interval_traits.hpp" 21 #include "interval_concept.hpp" 22 23 #include "rectangle_data.hpp" 24 #include "rectangle_traits.hpp" 25 26 namespace boost { namespace polygon{ 27 struct rectangle_concept {}; 28 29 template <typename T> 30 struct is_rectangle_concept { typedef gtl_no type; }; 31 template <> 32 struct is_rectangle_concept<rectangle_concept> { typedef gtl_yes type; }; 33 34 template <typename T> 35 struct is_mutable_rectangle_concept { typedef gtl_no type; }; 36 template <> 37 struct is_mutable_rectangle_concept<rectangle_concept> { typedef gtl_yes type; }; 38 39 template <> 40 struct geometry_domain<rectangle_concept> { typedef manhattan_domain type; }; 41 42 template <typename T, typename CT> 43 struct rectangle_interval_type_by_concept { typedef void type; }; 44 template <typename T> 45 struct rectangle_interval_type_by_concept<T, gtl_yes> { typedef typename rectangle_traits<T>::interval_type type; }; 46 47 template <typename T> 48 struct rectangle_interval_type { 49 typedef typename rectangle_interval_type_by_concept<T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type; 50 }; 51 52 template <typename T, typename CT> 53 struct rectangle_coordinate_type_by_concept { typedef void type; }; 54 template <typename T> 55 struct rectangle_coordinate_type_by_concept<T, gtl_yes> { typedef typename rectangle_traits<T>::coordinate_type type; }; 56 57 template <typename T> 58 struct rectangle_coordinate_type { 59 typedef typename rectangle_coordinate_type_by_concept<T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type; 60 }; 61 62 template <typename T, typename CT> 63 struct rectangle_difference_type_by_concept { typedef void type; }; 64 template <typename T> 65 struct rectangle_difference_type_by_concept<T, gtl_yes> { 66 typedef typename coordinate_traits<typename rectangle_traits<T>::coordinate_type>::coordinate_difference type; }; 67 68 template <typename T> 69 struct rectangle_difference_type { 70 typedef typename rectangle_difference_type_by_concept< 71 T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type; 72 }; 73 74 template <typename T, typename CT> 75 struct rectangle_distance_type_by_concept { typedef void type; }; 76 template <typename T> 77 struct rectangle_distance_type_by_concept<T, gtl_yes> { 78 typedef typename coordinate_traits<typename rectangle_coordinate_type<T>::type>::coordinate_distance type; }; 79 80 template <typename T> 81 struct rectangle_distance_type { 82 typedef typename rectangle_distance_type_by_concept< 83 T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type; 84 }; 85 86 struct y_r_get_interval : gtl_yes {}; 87 88 template <typename T> 89 typename enable_if< typename gtl_and<y_r_get_interval, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type, 90 typename rectangle_interval_type<T>::type>::type get(const T & rectangle,orientation_2d orient)91 get(const T& rectangle, orientation_2d orient) { 92 return rectangle_traits<T>::get(rectangle, orient); 93 } 94 95 struct y_r_h : gtl_yes {}; 96 97 template <typename T> 98 typename enable_if< typename gtl_and<y_r_h, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type, 99 typename rectangle_interval_type<T>::type>::type horizontal(const T & rectangle)100 horizontal(const T& rectangle) { 101 return rectangle_traits<T>::get(rectangle, HORIZONTAL); 102 } 103 104 struct y_r_v : gtl_yes {}; 105 106 template <typename T> 107 typename enable_if< typename gtl_and<y_r_v, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type, 108 typename rectangle_interval_type<T>::type>::type vertical(const T & rectangle)109 vertical(const T& rectangle) { 110 return rectangle_traits<T>::get(rectangle, VERTICAL); 111 } 112 113 struct y_r_set : gtl_yes {}; 114 115 template <orientation_2d_enum orient, typename T, typename T2> 116 typename enable_if< typename gtl_and_3<y_r_set, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type, 117 typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type, 118 void>::type set(T & rectangle,const T2 & interval)119 set(T& rectangle, const T2& interval) { 120 rectangle_mutable_traits<T>::set(rectangle, orient, interval); 121 } 122 123 struct y_r_set2 : gtl_yes {}; 124 125 template <typename T, typename T2> 126 typename enable_if< typename gtl_and_3<y_r_set2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type, 127 typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type, 128 void>::type set(T & rectangle,orientation_2d orient,const T2 & interval)129 set(T& rectangle, orientation_2d orient, const T2& interval) { 130 rectangle_mutable_traits<T>::set(rectangle, orient, interval); 131 } 132 133 struct y_r_h2 : gtl_yes {}; 134 135 template <typename T, typename T2> 136 typename enable_if< typename gtl_and_3<y_r_h2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type, 137 typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type, 138 void>::type horizontal(T & rectangle,const T2 & interval)139 horizontal(T& rectangle, const T2& interval) { 140 rectangle_mutable_traits<T>::set(rectangle, HORIZONTAL, interval); 141 } 142 143 struct y_r_v2 : gtl_yes {}; 144 145 template <typename T, typename T2> 146 typename enable_if< 147 typename gtl_and_3<y_r_v2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type, 148 typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type, void>::type vertical(T & rectangle,const T2 & interval)149 vertical(T& rectangle, const T2& interval) { 150 rectangle_mutable_traits<T>::set(rectangle, VERTICAL, interval); 151 } 152 153 struct y_r_construct : gtl_yes {}; 154 155 template <typename T, typename T2, typename T3> 156 typename enable_if< typename gtl_and<y_r_construct, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type>::type, 157 T>::type construct(const T2 & interval_horizontal,const T3 & interval_vertical)158 construct(const T2& interval_horizontal, 159 const T3& interval_vertical) { 160 return rectangle_mutable_traits<T>::construct(interval_horizontal, interval_vertical); } 161 162 struct y_r_construct2 : gtl_yes {}; 163 164 template <typename T, typename coord_type> 165 typename enable_if< typename gtl_and<y_r_construct2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type>::type, 166 T>::type construct(coord_type xl,coord_type yl,coord_type xh,coord_type yh)167 construct(coord_type xl, coord_type yl, coord_type xh, coord_type yh) { 168 return rectangle_mutable_traits<T>::construct(interval_data<coord_type>(xl, xh), 169 interval_data<coord_type>(yl, yh)); 170 } 171 172 struct y_r_cconstruct : gtl_yes {}; 173 174 template <typename T, typename T2> 175 typename enable_if< 176 typename gtl_and_3<y_r_cconstruct, 177 typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type, 178 typename is_rectangle_concept<typename geometry_concept<T2>::type>::type>::type, 179 T>::type copy_construct(const T2 & rectangle)180 copy_construct(const T2& rectangle) { 181 return construct<T> (get(rectangle, HORIZONTAL), get(rectangle, VERTICAL)); 182 } 183 184 struct y_r_assign : gtl_yes {}; 185 186 template <typename rectangle_type_1, typename rectangle_type_2> 187 typename enable_if< 188 typename gtl_and_3< y_r_assign, 189 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 190 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 191 rectangle_type_1>::type & assign(rectangle_type_1 & lvalue,const rectangle_type_2 & rvalue)192 assign(rectangle_type_1& lvalue, const rectangle_type_2& rvalue) { 193 set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL)); 194 set(lvalue, VERTICAL, get(rvalue, VERTICAL)); 195 return lvalue; 196 } 197 198 struct y_r_equiv : gtl_yes {}; 199 200 template <typename T, typename T2> 201 typename enable_if< 202 typename gtl_and_3< y_r_equiv, 203 typename is_rectangle_concept<typename geometry_concept<T>::type>::type, 204 typename is_rectangle_concept<typename geometry_concept<T2>::type>::type>::type, 205 bool>::type equivalence(const T & rect1,const T2 & rect2)206 equivalence(const T& rect1, const T2& rect2) { 207 return equivalence(get(rect1, HORIZONTAL), get(rect2, HORIZONTAL)) && 208 equivalence(get(rect1, VERTICAL), get(rect2, VERTICAL)); 209 } 210 211 struct y_r_get : gtl_yes {}; 212 213 template <typename rectangle_type> 214 typename enable_if< typename gtl_and<y_r_get, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 215 typename rectangle_coordinate_type<rectangle_type>::type>::type get(const rectangle_type & rectangle,orientation_2d orient,direction_1d dir)216 get(const rectangle_type& rectangle, orientation_2d orient, direction_1d dir) { 217 return get(rectangle_traits<rectangle_type>::get(rectangle, orient), dir); 218 } 219 220 struct y_r_set3 : gtl_yes {}; 221 222 template <typename rectangle_type> 223 typename enable_if<typename gtl_and<y_r_set3, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type set(rectangle_type & rectangle,orientation_2d orient,direction_1d dir,typename rectangle_coordinate_type<rectangle_type>::type value)224 set(rectangle_type& rectangle, orientation_2d orient, direction_1d dir, 225 typename rectangle_coordinate_type<rectangle_type>::type value) { 226 typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient); 227 set(ivl, dir, value); 228 set(rectangle, orient, ivl); 229 } 230 231 struct y_r_xl : gtl_yes {}; 232 233 template <typename rectangle_type> 234 typename enable_if< typename gtl_and<y_r_xl, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 235 typename rectangle_coordinate_type<rectangle_type>::type>::type xl(const rectangle_type & rectangle)236 xl(const rectangle_type& rectangle) { 237 return get(rectangle, HORIZONTAL, LOW); 238 } 239 240 struct y_r_xl2 : gtl_yes {}; 241 242 template <typename rectangle_type> 243 typename enable_if<typename gtl_and<y_r_xl2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type xl(rectangle_type & rectangle,typename rectangle_coordinate_type<rectangle_type>::type value)244 xl(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) { 245 return set(rectangle, HORIZONTAL, LOW, value); 246 } 247 248 struct y_r_xh : gtl_yes {}; 249 250 template <typename rectangle_type> 251 typename enable_if< typename gtl_and<y_r_xh, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 252 typename rectangle_coordinate_type<rectangle_type>::type>::type xh(const rectangle_type & rectangle)253 xh(const rectangle_type& rectangle) { 254 return get(rectangle, HORIZONTAL, HIGH); 255 } 256 257 struct y_r_xh2 : gtl_yes {}; 258 259 template <typename rectangle_type> 260 typename enable_if<typename gtl_and<y_r_xh2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type xh(rectangle_type & rectangle,typename rectangle_coordinate_type<rectangle_type>::type value)261 xh(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) { 262 return set(rectangle, HORIZONTAL, HIGH, value); 263 } 264 265 struct y_r_yl : gtl_yes {}; 266 267 template <typename rectangle_type> 268 typename enable_if< typename gtl_and<y_r_yl, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 269 typename rectangle_coordinate_type<rectangle_type>::type>::type yl(const rectangle_type & rectangle)270 yl(const rectangle_type& rectangle) { 271 return get(rectangle, VERTICAL, LOW); 272 } 273 274 struct y_r_yl2 : gtl_yes {}; 275 276 template <typename rectangle_type> 277 typename enable_if<typename gtl_and<y_r_yl2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type yl(rectangle_type & rectangle,typename rectangle_coordinate_type<rectangle_type>::type value)278 yl(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) { 279 return set(rectangle, VERTICAL, LOW, value); 280 } 281 282 struct y_r_yh : gtl_yes {}; 283 284 template <typename rectangle_type> 285 typename enable_if< typename gtl_and<y_r_yh, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 286 typename rectangle_coordinate_type<rectangle_type>::type>::type yh(const rectangle_type & rectangle)287 yh(const rectangle_type& rectangle) { 288 return get(rectangle, VERTICAL, HIGH); 289 } 290 291 struct y_r_yh2 : gtl_yes {}; 292 293 template <typename rectangle_type> 294 typename enable_if<typename gtl_and<y_r_yh2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type yh(rectangle_type & rectangle,typename rectangle_coordinate_type<rectangle_type>::type value)295 yh(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) { 296 return set(rectangle, VERTICAL, HIGH, value); 297 } 298 299 struct y_r_ll : gtl_yes {}; 300 301 template <typename rectangle_type> 302 typename enable_if<typename gtl_and<y_r_ll, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 303 point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type ll(const rectangle_type & rectangle)304 ll(const rectangle_type& rectangle) { 305 return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xl(rectangle), yl(rectangle)); 306 } 307 308 struct y_r_lr : gtl_yes {}; 309 310 template <typename rectangle_type> 311 typename enable_if<typename gtl_and<y_r_lr, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 312 point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type lr(const rectangle_type & rectangle)313 lr(const rectangle_type& rectangle) { 314 return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xh(rectangle), yl(rectangle)); 315 } 316 317 struct y_r_ul : gtl_yes {}; 318 319 template <typename rectangle_type> 320 typename enable_if<typename gtl_and<y_r_ul, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 321 point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type ul(const rectangle_type & rectangle)322 ul(const rectangle_type& rectangle) { 323 return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xl(rectangle), yh(rectangle)); 324 } 325 326 struct y_r_ur : gtl_yes {}; 327 328 template <typename rectangle_type> 329 typename enable_if<typename gtl_and<y_r_ur, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 330 point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type ur(const rectangle_type & rectangle)331 ur(const rectangle_type& rectangle) { 332 return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xh(rectangle), yh(rectangle)); 333 } 334 335 struct y_r_contains : gtl_yes {}; 336 337 template <typename rectangle_type, typename rectangle_type_2> 338 typename enable_if< typename gtl_and_3<y_r_contains, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 339 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 340 bool>::type contains(const rectangle_type & rectangle,const rectangle_type_2 rectangle_contained,bool consider_touch=true)341 contains(const rectangle_type& rectangle, const rectangle_type_2 rectangle_contained, 342 bool consider_touch = true) { 343 return contains(horizontal(rectangle), horizontal(rectangle_contained), consider_touch) && 344 contains(vertical(rectangle), vertical(rectangle_contained), consider_touch); 345 } 346 347 struct y_r_contains2 : gtl_yes {}; 348 349 template <typename rectangle_type, typename point_type> 350 typename enable_if< typename gtl_and_3<y_r_contains2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 351 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, bool>::type contains(const rectangle_type & rectangle,const point_type point_contained,bool consider_touch=true)352 contains(const rectangle_type& rectangle, const point_type point_contained, 353 bool consider_touch = true) { 354 return contains(horizontal(rectangle), x(point_contained), consider_touch) && 355 contains(vertical(rectangle), y(point_contained), consider_touch); 356 } 357 358 struct y_r_set_points : gtl_yes {}; 359 360 // set all four coordinates based upon two points 361 template <typename rectangle_type, typename point_type_1, typename point_type_2> 362 typename enable_if< typename gtl_and_4< y_r_set_points, 363 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 364 typename is_point_concept<typename geometry_concept<point_type_1>::type>::type, 365 typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type, 366 rectangle_type>::type & set_points(rectangle_type & rectangle,const point_type_1 & p1,const point_type_2 & p2)367 set_points(rectangle_type& rectangle, const point_type_1& p1, 368 const point_type_2& p2) { 369 typedef typename rectangle_coordinate_type<rectangle_type>::type Unit; 370 Unit x1(x(p1)); 371 Unit x2(x(p2)); 372 Unit y1(y(p1)); 373 Unit y2(y(p2)); 374 horizontal(rectangle, construct<typename rectangle_interval_type<rectangle_type>::type>(x1, x2)); 375 vertical(rectangle, construct<typename rectangle_interval_type<rectangle_type>::type>(y1, y2)); 376 return rectangle; 377 } 378 379 struct y_r_move : gtl_yes {}; 380 381 // move rectangle by delta in orient 382 template <typename rectangle_type> 383 typename enable_if< typename gtl_and<y_r_move, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 384 rectangle_type>::type & move(rectangle_type & rectangle,orientation_2d orient,typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference delta)385 move(rectangle_type& rectangle, orientation_2d orient, 386 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference delta) { 387 typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient); 388 move(ivl, delta); 389 set(rectangle, orient, ivl); 390 return rectangle; 391 } 392 393 struct y_r_convolve : gtl_yes {}; 394 395 // convolve this with b 396 template <typename rectangle_type_1, typename rectangle_type_2> 397 typename enable_if< 398 typename gtl_and_3< y_r_convolve, 399 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 400 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 401 rectangle_type_1>::type & convolve(rectangle_type_1 & rectangle,const rectangle_type_2 & convolution_rectangle)402 convolve(rectangle_type_1& rectangle, 403 const rectangle_type_2& convolution_rectangle) { 404 typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle); 405 horizontal(rectangle, convolve(ivl, horizontal(convolution_rectangle))); 406 ivl = vertical(rectangle); 407 vertical(rectangle, convolve(ivl, vertical(convolution_rectangle))); 408 return rectangle; 409 } 410 411 struct y_r_deconvolve : gtl_yes {}; 412 413 // deconvolve this with b 414 template <typename rectangle_type_1, typename rectangle_type_2> 415 typename enable_if< typename gtl_and_3< y_r_deconvolve, 416 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 417 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 418 rectangle_type_1>::type & deconvolve(rectangle_type_1 & rectangle,const rectangle_type_2 & convolution_rectangle)419 deconvolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) { 420 typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle); 421 horizontal(rectangle, deconvolve(ivl, horizontal(convolution_rectangle))); 422 ivl = vertical(rectangle); 423 vertical(rectangle, deconvolve(ivl, vertical(convolution_rectangle))); 424 return rectangle; 425 } 426 427 struct y_r_reconvolve : gtl_yes {}; 428 429 // reflectedConvolve this with b 430 template <typename rectangle_type_1, typename rectangle_type_2> 431 typename enable_if< 432 typename gtl_and_3<y_r_reconvolve, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 433 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 434 rectangle_type_1>::type & reflected_convolve(rectangle_type_1 & rectangle,const rectangle_type_2 & convolution_rectangle)435 reflected_convolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) { 436 typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle); 437 horizontal(rectangle, reflected_convolve(ivl, horizontal(convolution_rectangle))); 438 ivl = vertical(rectangle); 439 vertical(rectangle, reflected_convolve(ivl, vertical(convolution_rectangle))); 440 return rectangle; 441 } 442 443 struct y_r_redeconvolve : gtl_yes {}; 444 445 // reflectedDeconvolve this with b 446 // deconvolve this with b 447 template <typename rectangle_type_1, typename rectangle_type_2> 448 typename enable_if< 449 typename gtl_and_3<y_r_redeconvolve, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 450 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 451 rectangle_type_1>::type & reflected_deconvolve(rectangle_type_1 & rectangle,const rectangle_type_2 & convolution_rectangle)452 reflected_deconvolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) { 453 typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle); 454 horizontal(rectangle, reflected_deconvolve(ivl, horizontal(convolution_rectangle))); 455 ivl = vertical(rectangle); 456 vertical(rectangle, reflected_deconvolve(ivl, vertical(convolution_rectangle))); 457 return rectangle; 458 } 459 460 struct y_r_convolve2 : gtl_yes {}; 461 462 // convolve with point 463 template <typename rectangle_type, typename point_type> 464 typename enable_if< typename gtl_and_3<y_r_convolve2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 465 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, 466 rectangle_type>::type & convolve(rectangle_type & rectangle,const point_type & convolution_point)467 convolve(rectangle_type& rectangle, const point_type& convolution_point) { 468 typename rectangle_interval_type<rectangle_type>::type ivl = horizontal(rectangle); 469 horizontal(rectangle, convolve(ivl, x(convolution_point))); 470 ivl = vertical(rectangle); 471 vertical(rectangle, convolve(ivl, y(convolution_point))); 472 return rectangle; 473 } 474 475 struct y_r_deconvolve2 : gtl_yes {}; 476 477 // deconvolve with point 478 template <typename rectangle_type, typename point_type> 479 typename enable_if< 480 typename gtl_and_3<y_r_deconvolve2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 481 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, rectangle_type>::type & deconvolve(rectangle_type & rectangle,const point_type & convolution_point)482 deconvolve(rectangle_type& rectangle, const point_type& convolution_point) { 483 typename rectangle_interval_type<rectangle_type>::type ivl = horizontal(rectangle); 484 horizontal(rectangle, deconvolve(ivl, x(convolution_point))); 485 ivl = vertical(rectangle); 486 vertical(rectangle, deconvolve(ivl, y(convolution_point))); 487 return rectangle; 488 } 489 490 struct y_r_delta : gtl_yes {}; 491 492 // get the magnitude of the interval range depending on orient 493 template <typename rectangle_type> 494 typename enable_if< typename gtl_and<y_r_delta, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 495 typename rectangle_difference_type<rectangle_type>::type>::type delta(const rectangle_type & rectangle,orientation_2d orient)496 delta(const rectangle_type& rectangle, orientation_2d orient) { 497 return delta(get(rectangle, orient)); 498 } 499 500 struct y_r_area : gtl_yes {}; 501 502 // get the area of the rectangle 503 template <typename rectangle_type> 504 typename enable_if< typename gtl_and<y_r_area, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 505 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::manhattan_area_type>::type area(const rectangle_type & rectangle)506 area(const rectangle_type& rectangle) { 507 typedef typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::manhattan_area_type area_type; 508 return (area_type)delta(rectangle, HORIZONTAL) * (area_type)delta(rectangle, VERTICAL); 509 } 510 511 struct y_r_go : gtl_yes {}; 512 513 // returns the orientation of the longest side 514 template <typename rectangle_type> 515 typename enable_if<typename gtl_and<y_r_go, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 516 orientation_2d>::type guess_orientation(const rectangle_type & rectangle)517 guess_orientation(const rectangle_type& rectangle) { 518 return delta(rectangle, HORIZONTAL) >= delta(rectangle, VERTICAL) ? 519 HORIZONTAL : VERTICAL; 520 } 521 522 struct y_r_half_p : gtl_yes {}; 523 524 // get the half perimeter of the rectangle 525 template <typename rectangle_type> 526 typename enable_if< typename gtl_and<y_r_half_p, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 527 typename rectangle_difference_type<rectangle_type>::type>::type half_perimeter(const rectangle_type & rectangle)528 half_perimeter(const rectangle_type& rectangle) { 529 return delta(rectangle, HORIZONTAL) + delta(rectangle, VERTICAL); 530 } 531 532 struct y_r_perimeter : gtl_yes {}; 533 534 // get the perimeter of the rectangle 535 template <typename rectangle_type> 536 typename enable_if< typename gtl_and<y_r_perimeter, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 537 typename rectangle_difference_type<rectangle_type>::type>::type perimeter(const rectangle_type & rectangle)538 perimeter(const rectangle_type& rectangle) { 539 return 2 * half_perimeter(rectangle); 540 } 541 542 struct y_r_intersects : gtl_yes {}; 543 544 // check if Rectangle b intersects `this` Rectangle 545 // [in] b Rectangle that will be checked 546 // [in] considerTouch If true, return true even if b touches the boundary 547 // [ret] . true if `t` intersects b 548 template <typename rectangle_type_1, typename rectangle_type_2> 549 typename enable_if< 550 typename gtl_and_3<y_r_intersects, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 551 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 552 bool>::type intersects(const rectangle_type_1 & rectangle,const rectangle_type_2 & b,bool consider_touch=true)553 intersects(const rectangle_type_1& rectangle, const rectangle_type_2& b, bool consider_touch = true) { 554 return intersects(horizontal(rectangle), horizontal(b), consider_touch) && 555 intersects(vertical(rectangle), vertical(b), consider_touch); 556 } 557 558 struct y_r_b_intersect : gtl_yes {}; 559 560 // Check if boundaries of Rectangle b and `this` Rectangle intersect 561 // [in] b Rectangle that will be checked 562 // [in] considerTouch If true, return true even if p is on the foundary 563 // [ret] . true if `t` contains p 564 template <typename rectangle_type_1, typename rectangle_type_2> 565 typename enable_if< 566 typename gtl_and_3<y_r_b_intersect, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 567 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 568 bool>::type boundaries_intersect(const rectangle_type_1 & rectangle,const rectangle_type_2 & b,bool consider_touch=true)569 boundaries_intersect(const rectangle_type_1& rectangle, const rectangle_type_2& b, 570 bool consider_touch = true) { 571 return (intersects(rectangle, b, consider_touch) && 572 !(contains(rectangle, b, !consider_touch)) && 573 !(contains(b, rectangle, !consider_touch))); 574 } 575 576 struct y_r_b_abuts : gtl_yes {}; 577 578 // check if b is touching 'this' on the end specified by dir 579 template <typename rectangle_type_1, typename rectangle_type_2> 580 typename enable_if< typename gtl_and_3<y_r_b_abuts, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 581 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 582 bool>::type abuts(const rectangle_type_1 & rectangle,const rectangle_type_2 & b,direction_2d dir)583 abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b, 584 direction_2d dir) { 585 return 586 abuts(get(rectangle, orientation_2d(dir)), 587 get(b, orientation_2d(dir)), 588 direction_1d(dir)) && 589 intersects(get(rectangle, orientation_2d(dir).get_perpendicular()), 590 get(b, orientation_2d(dir).get_perpendicular()), true); 591 } 592 593 struct y_r_b_abuts2 : gtl_yes {}; 594 595 // check if they are touching in the given orientation 596 template <typename rectangle_type_1, typename rectangle_type_2> 597 typename enable_if< typename gtl_and_3<y_r_b_abuts2, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 598 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 599 bool>::type abuts(const rectangle_type_1 & rectangle,const rectangle_type_2 & b,orientation_2d orient)600 abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b, 601 orientation_2d orient) { 602 return 603 abuts(get(rectangle, orient), get(b, orient)) && 604 intersects(get(rectangle, orient.get_perpendicular()), 605 get(b, orient.get_perpendicular()), true); 606 } 607 608 struct y_r_b_abuts3 : gtl_yes {}; 609 610 // check if they are touching but not overlapping 611 template <typename rectangle_type_1, typename rectangle_type_2> 612 typename enable_if< typename gtl_and_3<y_r_b_abuts3, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 613 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 614 bool>::type abuts(const rectangle_type_1 & rectangle,const rectangle_type_2 & b)615 abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b) { 616 return abuts(rectangle, b, HORIZONTAL) || abuts(rectangle, b, VERTICAL); 617 } 618 619 struct y_r_b_intersect2 : gtl_yes {}; 620 621 // intersect rectangle with interval on orient 622 template <typename rectangle_type, typename interval_type> 623 typename enable_if< 624 typename gtl_and_3<y_r_b_intersect2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 625 typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, 626 bool>::type intersect(rectangle_type & rectangle,const interval_type & b,orientation_2d orient,bool consider_touch=true)627 intersect(rectangle_type& rectangle, const interval_type& b, 628 orientation_2d orient, bool consider_touch = true) { 629 typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient); 630 if(intersect(ivl, b, consider_touch)) { 631 set(rectangle, orient, ivl); 632 return true; 633 } 634 return false; 635 } 636 637 struct y_r_b_intersect3 : gtl_yes {}; 638 639 // clip rectangle to b 640 template <typename rectangle_type_1, typename rectangle_type_2> 641 typename enable_if< typename gtl_and_3<y_r_b_intersect3, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 642 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 643 bool>::type intersect(rectangle_type_1 & rectangle,const rectangle_type_2 & b,bool consider_touch=true)644 intersect(rectangle_type_1& rectangle, const rectangle_type_2& b, bool consider_touch = true) { 645 if(intersects(rectangle, b)) { 646 intersect(rectangle, horizontal(b), HORIZONTAL, consider_touch); 647 intersect(rectangle, vertical(b), VERTICAL, consider_touch); 648 return true; 649 } 650 return false; 651 } 652 653 struct y_r_g_intersect : gtl_yes {}; 654 655 // Sets this to the generalized intersection of this and the given rectangle 656 template <typename rectangle_type_1, typename rectangle_type_2> 657 typename enable_if< typename gtl_and_3<y_r_g_intersect, 658 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 659 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 660 rectangle_type_1>::type & generalized_intersect(rectangle_type_1 & rectangle,const rectangle_type_2 & b)661 generalized_intersect(rectangle_type_1& rectangle, const rectangle_type_2& b) { 662 typename rectangle_interval_type<rectangle_type_1>::type ivl = get(rectangle, HORIZONTAL); 663 generalized_intersect(ivl, horizontal(b)); 664 horizontal(rectangle, ivl); 665 ivl = vertical(rectangle); 666 generalized_intersect(ivl, vertical(b)); 667 vertical(rectangle, ivl); 668 return rectangle; 669 } 670 671 struct y_r_bloat : gtl_yes {}; 672 673 // bloat the interval specified by orient by bloating 674 template <typename rectangle_type> 675 typename enable_if<typename gtl_and<y_r_bloat, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 676 rectangle_type>::type & bloat(rectangle_type & rectangle,orientation_2d orient,typename rectangle_coordinate_type<rectangle_type>::type bloating)677 bloat(rectangle_type& rectangle, orientation_2d orient, 678 typename rectangle_coordinate_type<rectangle_type>::type bloating) { 679 typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient); 680 bloat(ivl, bloating); 681 set(rectangle, orient, ivl); 682 return rectangle; 683 } 684 685 struct y_r_bloat2 : gtl_yes {}; 686 687 // bloat the Rectangle by bloating 688 template <typename rectangle_type> 689 typename enable_if<typename gtl_and<y_r_bloat2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 690 rectangle_type>::type & bloat(rectangle_type & rectangle,typename rectangle_coordinate_type<rectangle_type>::type bloating)691 bloat(rectangle_type& rectangle, 692 typename rectangle_coordinate_type<rectangle_type>::type bloating) { 693 bloat(rectangle, HORIZONTAL, bloating); 694 return bloat(rectangle, VERTICAL, bloating); 695 } 696 697 struct y_r_bloat3 : gtl_yes {}; 698 699 // bloat the interval cooresponding to orient by bloating in dir direction 700 template <typename rectangle_type> 701 typename enable_if<typename gtl_and<y_r_bloat3, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 702 rectangle_type>::type & bloat(rectangle_type & rectangle,direction_2d dir,typename rectangle_coordinate_type<rectangle_type>::type bloating)703 bloat(rectangle_type& rectangle, direction_2d dir, 704 typename rectangle_coordinate_type<rectangle_type>::type bloating) { 705 typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orientation_2d(dir)); 706 bloat(ivl, direction_1d(dir), bloating); 707 set(rectangle, orientation_2d(dir), ivl); 708 return rectangle; 709 } 710 711 struct y_r_shrink : gtl_yes {}; 712 713 // shrink the interval specified by orient by bloating 714 template <typename rectangle_type> 715 typename enable_if<typename gtl_and<y_r_shrink, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 716 rectangle_type>::type & shrink(rectangle_type & rectangle,orientation_2d orient,typename rectangle_coordinate_type<rectangle_type>::type shrinking)717 shrink(rectangle_type& rectangle, orientation_2d orient, 718 typename rectangle_coordinate_type<rectangle_type>::type shrinking) { 719 return bloat(rectangle, orient, -shrinking); 720 } 721 722 struct y_r_shrink2 : gtl_yes {}; 723 724 // shrink the Rectangle by bloating 725 template <typename rectangle_type> 726 typename enable_if<typename gtl_and<y_r_shrink2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 727 rectangle_type>::type & shrink(rectangle_type & rectangle,typename rectangle_coordinate_type<rectangle_type>::type shrinking)728 shrink(rectangle_type& rectangle, 729 typename rectangle_coordinate_type<rectangle_type>::type shrinking) { 730 return bloat(rectangle, -shrinking); 731 } 732 733 struct y_r_shrink3 : gtl_yes {}; 734 735 // shrink the interval cooresponding to orient by bloating in dir direction 736 template <typename rectangle_type> 737 typename enable_if<typename gtl_and<y_r_shrink3, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 738 rectangle_type>::type & shrink(rectangle_type & rectangle,direction_2d dir,typename rectangle_coordinate_type<rectangle_type>::type shrinking)739 shrink(rectangle_type& rectangle, direction_2d dir, 740 typename rectangle_coordinate_type<rectangle_type>::type shrinking) { 741 return bloat(rectangle, dir, -shrinking); 742 } 743 744 struct y_r_encompass : gtl_yes {}; 745 746 // encompass interval on orient 747 template <typename rectangle_type, typename interval_type> 748 typename enable_if<typename gtl_and_3< 749 y_r_encompass, 750 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 751 typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, 752 bool>::type encompass(rectangle_type & rectangle,const interval_type & b,orientation_2d orient)753 encompass(rectangle_type& rectangle, const interval_type& b, orientation_2d orient) { 754 typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient); 755 if(encompass(ivl, b)) { 756 set(rectangle, orient, ivl); 757 return true; 758 } 759 return false; 760 } 761 762 struct y_r_encompass2 : gtl_yes {}; 763 764 // enlarge rectangle to encompass the Rectangle b 765 template <typename rectangle_type_1, typename rectangle_type_2> 766 typename enable_if< typename gtl_and_3< 767 y_r_encompass2, 768 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 769 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type >::type, 770 bool>::type encompass(rectangle_type_1 & rectangle,const rectangle_type_2 & b)771 encompass(rectangle_type_1& rectangle, const rectangle_type_2& b) { 772 //note that operator | is intentional because both should be called regardless 773 return encompass(rectangle, horizontal(b), HORIZONTAL) | 774 encompass(rectangle, vertical(b), VERTICAL); 775 } 776 777 struct y_r_encompass3 : gtl_yes {}; 778 779 // enlarge rectangle to encompass the point b 780 template <typename rectangle_type_1, typename point_type> 781 typename enable_if<typename gtl_and_3< 782 y_r_encompass3, 783 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 784 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, 785 bool>::type encompass(rectangle_type_1 & rectangle,const point_type & b)786 encompass(rectangle_type_1& rectangle, const point_type& b) { 787 typename rectangle_interval_type<rectangle_type_1>::type hivl, vivl; 788 hivl = horizontal(rectangle); 789 vivl = vertical(rectangle); 790 //note that operator | is intentional because both should be called regardless 791 bool retval = encompass(hivl, x(b)) | encompass(vivl, y(b)); 792 if(retval) { 793 horizontal(rectangle, hivl); 794 vertical(rectangle, vivl); 795 } 796 return retval; 797 } 798 799 struct y_r_center : gtl_yes {}; 800 801 // returns the center of the rectangle 802 template <typename point_type, typename rectangle_type> 803 typename enable_if< 804 typename gtl_and_3<y_r_center, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type, 805 typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 806 bool>::type center(point_type & center_point,const rectangle_type & rectangle)807 center(point_type& center_point, const rectangle_type& rectangle) { 808 center_point = construct<point_type>(center(horizontal(rectangle)), 809 center(vertical(rectangle))); 810 return true; 811 } 812 813 struct y_r_get_corner : gtl_yes {}; 814 815 template <typename point_type, typename rectangle_type> 816 typename enable_if< 817 typename gtl_and_3<y_r_get_corner, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type, 818 typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 819 bool>::type get_corner(point_type & corner_point,const rectangle_type & rectangle,direction_2d direction_facing,direction_1d direction_turning)820 get_corner(point_type& corner_point, const rectangle_type& rectangle, direction_2d direction_facing, direction_1d direction_turning) { 821 typedef typename rectangle_coordinate_type<rectangle_type>::type Unit; 822 Unit u1 = get(rectangle, direction_facing); 823 Unit u2 = get(rectangle, direction_facing.turn(direction_turning)); 824 if(orientation_2d(direction_facing).to_int()) std::swap(u1, u2); 825 corner_point = construct<point_type>(u1, u2); 826 return true; 827 } 828 829 struct y_r_get_half : gtl_yes {}; 830 831 template <typename rectangle_type> 832 typename enable_if<typename gtl_and<y_r_get_half, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 833 rectangle_type>::type get_half(const rectangle_type & rectangle,direction_2d dir)834 get_half(const rectangle_type& rectangle, direction_2d dir) { 835 rectangle_type retval(rectangle); 836 set(retval, orientation_2d(dir), get_half(get(rectangle, orientation_2d(dir)), direction_1d(dir))); 837 return retval; 838 } 839 840 struct y_r_join_with : gtl_yes {}; 841 842 template <typename rectangle_type_1, typename rectangle_type_2> 843 typename enable_if< typename gtl_and_3<y_r_join_with, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 844 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 845 bool>::type join_with(rectangle_type_1 & rectangle,const rectangle_type_2 & b)846 join_with(rectangle_type_1& rectangle, const rectangle_type_2& b) { 847 typedef typename rectangle_interval_type<rectangle_type_1>::type Interval1; 848 typedef typename rectangle_interval_type<rectangle_type_2>::type Interval2; 849 Interval1 hi1 = get(rectangle, HORIZONTAL); 850 Interval1 vi1 = get(rectangle, VERTICAL); 851 Interval2 hi2 = get(b, HORIZONTAL), vi2 = get(b, VERTICAL); 852 Interval1 temp; 853 if (equivalence(hi1, hi2) && join_with(vi1, vi2)) { 854 vertical(rectangle, vi1); 855 return true; 856 } 857 if (equivalence(vi1, vi2) && join_with(hi1, hi2)) { 858 horizontal(rectangle, hi1); 859 return true; 860 } 861 return false; 862 } 863 864 struct y_r_eda2 : gtl_yes {}; 865 866 template <typename rectangle_type, typename point_type> 867 typename enable_if< typename gtl_and_3<y_r_eda2, 868 typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 869 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, 870 typename rectangle_difference_type<rectangle_type>::type>::type euclidean_distance(const rectangle_type & lvalue,const point_type & rvalue,orientation_2d orient)871 euclidean_distance(const rectangle_type& lvalue, const point_type& rvalue, orientation_2d orient) { 872 return euclidean_distance(get(lvalue, orient), get(rvalue, orient)); 873 } 874 875 struct y_r_eda : gtl_yes {}; 876 877 template <typename rectangle_type, typename rectangle_type_2> 878 typename enable_if< 879 typename gtl_and_3<y_r_eda, 880 typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 881 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 882 typename rectangle_difference_type<rectangle_type>::type>::type euclidean_distance(const rectangle_type & lvalue,const rectangle_type_2 & rvalue,orientation_2d orient)883 euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue, orientation_2d orient) { 884 return euclidean_distance(get(lvalue, orient), get(rvalue, orient)); 885 } 886 887 struct y_r_sed : gtl_yes {}; 888 889 template <typename rectangle_type, typename point_type> 890 typename enable_if< typename gtl_and_3<y_r_sed, 891 typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 892 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, 893 typename rectangle_difference_type<rectangle_type>::type>::type square_euclidean_distance(rectangle_type & lvalue,const point_type & rvalue)894 square_euclidean_distance(rectangle_type& lvalue, const point_type& rvalue) { 895 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist; 896 xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); 897 ydist = euclidean_distance(lvalue, rvalue, VERTICAL); 898 return (xdist * xdist) + (ydist * ydist); 899 } 900 901 struct y_r_sed2 : gtl_yes {}; 902 903 template <typename rectangle_type, typename rectangle_type_2> 904 typename enable_if< 905 typename gtl_and_3<y_r_sed2, typename is_rectangle_concept< typename geometry_concept<rectangle_type>::type>::type, 906 typename is_rectangle_concept< typename geometry_concept<rectangle_type_2>::type>::type>::type, 907 typename rectangle_difference_type<rectangle_type>::type>::type square_euclidean_distance(const rectangle_type & lvalue,const rectangle_type_2 & rvalue)908 square_euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) { 909 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist; 910 xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); 911 ydist = euclidean_distance(lvalue, rvalue, VERTICAL); 912 return (xdist * xdist) + (ydist * ydist); 913 } 914 915 struct y_r_edist : gtl_yes {}; 916 917 template <typename rectangle_type, typename point_type> 918 typename enable_if< typename gtl_and_3<y_r_edist, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 919 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, 920 typename rectangle_distance_type<rectangle_type>::type>::type euclidean_distance(rectangle_type & lvalue,const point_type & rvalue)921 euclidean_distance(rectangle_type& lvalue, const point_type& rvalue) { 922 return std::sqrt((double)(square_euclidean_distance(lvalue, rvalue))); 923 } 924 925 struct y_r_edist2 : gtl_yes {}; 926 927 template <typename rectangle_type, typename rectangle_type_2> 928 typename enable_if< typename gtl_and_3<y_r_edist2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 929 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 930 typename rectangle_distance_type<rectangle_type>::type>::type euclidean_distance(const rectangle_type & lvalue,const rectangle_type_2 & rvalue)931 euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) { 932 double val = (int)square_euclidean_distance(lvalue, rvalue); 933 return std::sqrt(val); 934 } 935 936 struct y_r_mdist : gtl_yes {}; 937 938 template <typename rectangle_type, typename point_type> 939 typename enable_if< 940 typename gtl_and_3<y_r_mdist, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 941 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, 942 typename rectangle_difference_type<rectangle_type>::type>::type manhattan_distance(rectangle_type & lvalue,const point_type & rvalue)943 manhattan_distance(rectangle_type& lvalue, const point_type& rvalue) { 944 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist; 945 xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); 946 ydist = euclidean_distance(lvalue, rvalue, VERTICAL); 947 return xdist + ydist; 948 } 949 950 struct y_r_mdist2 : gtl_yes {}; 951 952 template <typename rectangle_type, typename rectangle_type_2> 953 typename enable_if< 954 typename gtl_and_3<y_r_mdist2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, 955 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 956 typename rectangle_difference_type<rectangle_type>::type>::type manhattan_distance(const rectangle_type & lvalue,const rectangle_type_2 & rvalue)957 manhattan_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) { 958 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist; 959 xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); 960 ydist = euclidean_distance(lvalue, rvalue, VERTICAL); 961 return xdist + ydist; 962 } 963 964 struct y_r_scale_up : gtl_yes {}; 965 966 template <typename rectangle_type> 967 typename enable_if<typename gtl_and<y_r_scale_up, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 968 rectangle_type>::type & scale_up(rectangle_type & rectangle,typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::unsigned_area_type factor)969 scale_up(rectangle_type& rectangle, 970 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::unsigned_area_type factor) { 971 typename rectangle_interval_type<rectangle_type>::type h = horizontal(rectangle); 972 horizontal(rectangle, scale_up(h, factor)); 973 typename rectangle_interval_type<rectangle_type>::type v = vertical(rectangle); 974 vertical(rectangle, scale_up(v, factor)); 975 return rectangle; 976 } 977 978 struct y_r_scale_down : gtl_yes {}; 979 980 template <typename rectangle_type> 981 typename enable_if<typename gtl_and<y_r_scale_down, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 982 rectangle_type>::type & scale_down(rectangle_type & rectangle,typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::unsigned_area_type factor)983 scale_down(rectangle_type& rectangle, 984 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::unsigned_area_type factor) { 985 typename rectangle_interval_type<rectangle_type>::type h = horizontal(rectangle); 986 horizontal(rectangle, scale_down(h, factor)); 987 typename rectangle_interval_type<rectangle_type>::type v = vertical(rectangle); 988 vertical(rectangle, scale_down(v, factor)); 989 return rectangle; 990 } 991 992 struct y_r_scale : gtl_yes {}; 993 994 template <typename rectangle_type, typename scaling_type> 995 typename enable_if<typename gtl_and<y_r_scale, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 996 rectangle_type>::type & scale(rectangle_type & rectangle,const scaling_type & scaling)997 scale(rectangle_type& rectangle, const scaling_type& scaling) { 998 point_data<typename rectangle_coordinate_type<rectangle_type>::type> llp(xl(rectangle), yl(rectangle)); 999 point_data<typename rectangle_coordinate_type<rectangle_type>::type> urp(xl(rectangle), yl(rectangle)); 1000 scale(llp, scaling); 1001 scale(urp, scaling); 1002 set_points(rectangle, llp, urp); 1003 return rectangle; 1004 } 1005 1006 struct y_r_transform : gtl_yes {}; 1007 1008 template <typename rectangle_type, typename transformation_type> 1009 typename enable_if<typename gtl_and<y_r_transform, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 1010 rectangle_type>::type & transform(rectangle_type & rectangle,const transformation_type & transformation)1011 transform(rectangle_type& rectangle, const transformation_type& transformation) { 1012 point_data<typename rectangle_coordinate_type<rectangle_type>::type> llp(xl(rectangle), yl(rectangle)); 1013 point_data<typename rectangle_coordinate_type<rectangle_type>::type> urp(xh(rectangle), yh(rectangle)); 1014 transform(llp, transformation); 1015 transform(urp, transformation); 1016 set_points(rectangle, llp, urp); 1017 return rectangle; 1018 } 1019 1020 template <typename rectangle_type_1, typename rectangle_type_2> 1021 class less_rectangle_concept { 1022 private: 1023 orientation_2d orient_; 1024 public: less_rectangle_concept(orientation_2d orient=VERTICAL)1025 inline less_rectangle_concept(orientation_2d orient = VERTICAL) : orient_(orient) {} 1026 typename enable_if< 1027 typename gtl_and< typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, 1028 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, 1029 bool>::type operator ()(const rectangle_type_1 & a,const rectangle_type_2 & b) const1030 operator () (const rectangle_type_1& a, 1031 const rectangle_type_2& b) const { 1032 typedef typename rectangle_coordinate_type<rectangle_type_1>::type Unit; 1033 Unit vl1 = get(get(a, orient_), LOW); 1034 Unit vl2 = get(get(b, orient_), LOW); 1035 if(vl1 > vl2) return false; 1036 if(vl1 == vl2) { 1037 orientation_2d perp = orient_.get_perpendicular(); 1038 Unit hl1 = get(get(a, perp), LOW); 1039 Unit hl2 = get(get(b, perp), LOW); 1040 if(hl1 > hl2) return false; 1041 if(hl1 == hl2) { 1042 Unit vh1 = get(get(a, orient_), HIGH); 1043 Unit vh2 = get(get(b, orient_), HIGH); 1044 if(vh1 > vh2) return false; 1045 if(vh1 == vh2) { 1046 Unit hh1 = get(get(a, perp), HIGH); 1047 Unit hh2 = get(get(b, perp), HIGH); 1048 return hh1 < hh2; 1049 } 1050 } 1051 } 1052 return true; 1053 } 1054 1055 }; 1056 1057 template <typename T> 1058 template <typename interval_type_1> set(orientation_2d orient,const interval_type_1 & interval)1059 inline void rectangle_data<T>::set(orientation_2d orient, const interval_type_1& interval) { 1060 assign(ranges_[orient.to_int()], interval); 1061 } 1062 1063 template <class T> 1064 template <class T2> operator =(const T2 & rvalue)1065 rectangle_data<T>& rectangle_data<T>::operator=(const T2& rvalue) { 1066 assign(*this, rvalue); 1067 return *this; 1068 } 1069 1070 template <class T> 1071 template <class T2> operator ==(const T2 & rvalue) const1072 bool rectangle_data<T>::operator==(const T2& rvalue) const { 1073 return equivalence(*this, rvalue); 1074 } 1075 1076 template <typename T> 1077 struct geometry_concept<rectangle_data<T> > { 1078 typedef rectangle_concept type; 1079 }; 1080 } 1081 } 1082 #endif 1083