rectangle_concept.hpp 49 KB

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