point_concept.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. // Boost.Polygon library point_concept.hpp header file
  2. // Copyright (c) Intel Corporation 2008.
  3. // Copyright (c) 2008-2012 Simonson Lucanus.
  4. // Copyright (c) 2012-2012 Andrii Sydorchuk.
  5. // See http://www.boost.org for updates, documentation, and revision history.
  6. // Use, modification and distribution is subject to the Boost Software License,
  7. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. #ifndef BOOST_POLYGON_POINT_CONCEPT_HPP
  10. #define BOOST_POLYGON_POINT_CONCEPT_HPP
  11. #include "isotropy.hpp"
  12. #include "point_traits.hpp"
  13. namespace boost {
  14. namespace polygon {
  15. struct point_concept {};
  16. template <typename ConceptType>
  17. struct is_point_concept {
  18. typedef gtl_no type;
  19. };
  20. template <>
  21. struct is_point_concept<point_concept> {
  22. typedef gtl_yes type;
  23. };
  24. template <typename ConceptType>
  25. struct is_mutable_point_concept {
  26. typedef gtl_no type;
  27. };
  28. template <>
  29. struct is_mutable_point_concept<point_concept> {
  30. typedef gtl_yes type;
  31. };
  32. template <typename GeometryType, typename BoolType>
  33. struct point_coordinate_type_by_concept {
  34. typedef void type;
  35. };
  36. template <typename GeometryType>
  37. struct point_coordinate_type_by_concept<GeometryType, gtl_yes> {
  38. typedef typename point_traits<GeometryType>::coordinate_type type;
  39. };
  40. template <typename GeometryType>
  41. struct point_coordinate_type {
  42. typedef typename point_coordinate_type_by_concept<
  43. GeometryType,
  44. typename is_point_concept<
  45. typename geometry_concept<GeometryType>::type
  46. >::type
  47. >::type type;
  48. };
  49. template <typename GeometryType, typename BoolType>
  50. struct point_difference_type_by_concept {
  51. typedef void type;
  52. };
  53. template <typename GeometryType>
  54. struct point_difference_type_by_concept<GeometryType, gtl_yes> {
  55. typedef typename coordinate_traits<
  56. typename point_traits<GeometryType>::coordinate_type
  57. >::coordinate_difference type;
  58. };
  59. template <typename GeometryType>
  60. struct point_difference_type {
  61. typedef typename point_difference_type_by_concept<
  62. GeometryType,
  63. typename is_point_concept<
  64. typename geometry_concept<GeometryType>::type
  65. >::type
  66. >::type type;
  67. };
  68. template <typename GeometryType, typename BoolType>
  69. struct point_distance_type_by_concept {
  70. typedef void type;
  71. };
  72. template <typename GeometryType>
  73. struct point_distance_type_by_concept<GeometryType, gtl_yes> {
  74. typedef typename coordinate_traits<
  75. typename point_coordinate_type<GeometryType>::type
  76. >::coordinate_distance type;
  77. };
  78. template <typename GeometryType>
  79. struct point_distance_type {
  80. typedef typename point_distance_type_by_concept<
  81. GeometryType,
  82. typename is_point_concept<
  83. typename geometry_concept<GeometryType>::type
  84. >::type
  85. >::type type;
  86. };
  87. struct y_pt_get : gtl_yes {};
  88. template <typename PointType>
  89. typename enable_if<
  90. typename gtl_and<
  91. y_pt_get,
  92. typename is_point_concept<
  93. typename geometry_concept<PointType>::type
  94. >::type
  95. >::type,
  96. typename point_coordinate_type<PointType>::type
  97. >::type get(const PointType& point, orientation_2d orient) {
  98. return point_traits<PointType>::get(point, orient);
  99. }
  100. struct y_pt_set : gtl_yes {};
  101. template <typename PointType>
  102. typename enable_if<
  103. typename gtl_and<
  104. y_pt_set,
  105. typename is_mutable_point_concept<
  106. typename geometry_concept<PointType>::type
  107. >::type
  108. >::type,
  109. void
  110. >::type set(PointType& point, orientation_2d orient,
  111. typename point_mutable_traits<PointType>::coordinate_type value) {
  112. point_mutable_traits<PointType>::set(point, orient, value);
  113. }
  114. struct y_pt_construct : gtl_yes {};
  115. template <typename PointType>
  116. typename enable_if<
  117. typename gtl_and<
  118. y_pt_construct,
  119. typename is_mutable_point_concept<
  120. typename geometry_concept<PointType>::type
  121. >::type
  122. >::type,
  123. PointType>::type construct(
  124. typename point_mutable_traits<PointType>::coordinate_type x,
  125. typename point_mutable_traits<PointType>::coordinate_type y) {
  126. return point_mutable_traits<PointType>::construct(x, y);
  127. }
  128. struct y_pt_assign : gtl_yes {};
  129. template <typename PointType1, typename PointType2>
  130. typename enable_if<
  131. typename gtl_and_3<
  132. y_pt_assign,
  133. typename is_mutable_point_concept<
  134. typename geometry_concept<PointType1>::type
  135. >::type,
  136. typename is_point_concept<
  137. typename geometry_concept<PointType2>::type
  138. >::type
  139. >::type,
  140. PointType1>::type& assign(PointType1& lvalue, const PointType2& rvalue) {
  141. set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL));
  142. set(lvalue, VERTICAL, get(rvalue, VERTICAL));
  143. return lvalue;
  144. }
  145. struct y_p_x : gtl_yes {};
  146. template <typename PointType>
  147. typename enable_if<
  148. typename gtl_and<
  149. y_p_x,
  150. typename is_point_concept<
  151. typename geometry_concept<PointType>::type
  152. >::type
  153. >::type,
  154. typename point_coordinate_type<PointType>::type
  155. >::type x(const PointType& point) {
  156. return get(point, HORIZONTAL);
  157. }
  158. struct y_p_y : gtl_yes {};
  159. template <typename PointType>
  160. typename enable_if<
  161. typename gtl_and<
  162. y_p_y,
  163. typename is_point_concept<
  164. typename geometry_concept<PointType>::type
  165. >::type
  166. >::type,
  167. typename point_coordinate_type<PointType>::type
  168. >::type y(const PointType& point) {
  169. return get(point, VERTICAL);
  170. }
  171. struct y_p_sx : gtl_yes {};
  172. template <typename PointType>
  173. typename enable_if<
  174. typename gtl_and<
  175. y_p_sx,
  176. typename is_mutable_point_concept<
  177. typename geometry_concept<PointType>::type
  178. >::type
  179. >::type,
  180. void>::type x(PointType& point,
  181. typename point_mutable_traits<PointType>::coordinate_type value) {
  182. set(point, HORIZONTAL, value);
  183. }
  184. struct y_p_sy : gtl_yes {};
  185. template <typename PointType>
  186. typename enable_if<
  187. typename gtl_and<
  188. y_p_sy,
  189. typename is_mutable_point_concept<
  190. typename geometry_concept<PointType>::type
  191. >::type
  192. >::type,
  193. void>::type y(PointType& point,
  194. typename point_mutable_traits<PointType>::coordinate_type value) {
  195. set(point, VERTICAL, value);
  196. }
  197. struct y_pt_equiv : gtl_yes {};
  198. template <typename PointType1, typename PointType2>
  199. typename enable_if<
  200. typename gtl_and_3<
  201. y_pt_equiv,
  202. typename is_point_concept<
  203. typename geometry_concept<PointType1>::type
  204. >::type,
  205. typename is_point_concept<
  206. typename geometry_concept<PointType2>::type
  207. >::type
  208. >::type,
  209. bool>::type equivalence(
  210. const PointType1& point1, const PointType2& point2) {
  211. return (x(point1) == x(point2)) && (y(point1) == y(point2));
  212. }
  213. struct y_pt_man_dist : gtl_yes {};
  214. template <typename PointType1, typename PointType2>
  215. typename enable_if<
  216. typename gtl_and_3<
  217. y_pt_man_dist,
  218. typename is_point_concept<
  219. typename geometry_concept<PointType1>::type
  220. >::type,
  221. typename is_point_concept<
  222. typename geometry_concept<PointType2>::type
  223. >::type
  224. >::type,
  225. typename point_difference_type<PointType1>::type>::type
  226. manhattan_distance(const PointType1& point1, const PointType2& point2) {
  227. return euclidean_distance(point1, point2, HORIZONTAL) +
  228. euclidean_distance(point1, point2, VERTICAL);
  229. }
  230. struct y_pt_ed1 : gtl_yes {};
  231. template <typename PointType1, typename PointType2>
  232. typename enable_if<
  233. typename gtl_and_3<
  234. y_pt_ed1,
  235. typename is_point_concept<
  236. typename geometry_concept<PointType1>::type
  237. >::type,
  238. typename is_point_concept<
  239. typename geometry_concept<PointType2>::type
  240. >::type
  241. >::type,
  242. typename point_difference_type<PointType1>::type>::type
  243. euclidean_distance(
  244. const PointType1& point1,
  245. const PointType2& point2,
  246. orientation_2d orient) {
  247. typename point_difference_type<PointType1>::type dif =
  248. get(point1, orient) - get(point2, orient);
  249. return (dif < 0) ? -dif : dif;
  250. }
  251. struct y_pt_eds : gtl_yes {};
  252. template <typename PointType1, typename PointType2>
  253. typename enable_if<
  254. typename gtl_and_3<
  255. y_pt_eds,
  256. typename is_point_concept<
  257. typename geometry_concept<PointType1>::type
  258. >::type,
  259. typename is_point_concept<
  260. typename geometry_concept<PointType2>::type
  261. >::type
  262. >::type,
  263. typename point_difference_type<PointType1>::type>::type
  264. distance_squared(const PointType1& point1, const PointType2& point2) {
  265. typename point_difference_type<PointType1>::type dx =
  266. euclidean_distance(point1, point2, HORIZONTAL);
  267. typename point_difference_type<PointType1>::type dy =
  268. euclidean_distance(point1, point2, VERTICAL);
  269. dx *= dx;
  270. dy *= dy;
  271. return dx + dy;
  272. }
  273. struct y_pt_ed2 : gtl_yes {};
  274. template <typename PointType1, typename PointType2>
  275. typename enable_if<
  276. typename gtl_and_3<
  277. y_pt_ed2,
  278. typename is_point_concept<
  279. typename geometry_concept<PointType1>::type
  280. >::type,
  281. typename is_point_concept<
  282. typename geometry_concept<PointType2>::type
  283. >::type
  284. >::type,
  285. typename point_distance_type<PointType1>::type>::type
  286. euclidean_distance(const PointType1& point1, const PointType2& point2) {
  287. return (std::sqrt)(
  288. static_cast<double>(distance_squared(point1, point2)));
  289. }
  290. struct y_pt_convolve : gtl_yes {};
  291. template <typename PointType1, typename PointType2>
  292. typename enable_if<
  293. typename gtl_and_3<
  294. y_pt_convolve,
  295. typename is_mutable_point_concept<
  296. typename geometry_concept<PointType1>::type
  297. >::type,
  298. typename is_point_concept<
  299. typename geometry_concept<PointType2>::type
  300. >::type
  301. >::type,
  302. PointType1>::type& convolve(PointType1& lvalue, const PointType2& rvalue) {
  303. x(lvalue, x(lvalue) + x(rvalue));
  304. y(lvalue, y(lvalue) + y(rvalue));
  305. return lvalue;
  306. }
  307. struct y_pt_deconvolve : gtl_yes {};
  308. template <typename PointType1, typename PointType2>
  309. typename enable_if<
  310. typename gtl_and_3<
  311. y_pt_deconvolve,
  312. typename is_mutable_point_concept<
  313. typename geometry_concept<PointType1>::type
  314. >::type,
  315. typename is_point_concept<
  316. typename geometry_concept<PointType2>::type
  317. >::type
  318. >::type,
  319. PointType1>::type& deconvolve(PointType1& lvalue, const PointType2& rvalue) {
  320. x(lvalue, x(lvalue) - x(rvalue));
  321. y(lvalue, y(lvalue) - y(rvalue));
  322. return lvalue;
  323. }
  324. struct y_pt_scale_up : gtl_yes {};
  325. template <typename PointType, typename CType>
  326. typename enable_if<
  327. typename gtl_and<
  328. y_pt_scale_up,
  329. typename is_mutable_point_concept<
  330. typename geometry_concept<PointType>::type
  331. >::type
  332. >::type,
  333. PointType>::type& scale_up(PointType& point, CType factor) {
  334. typedef typename point_coordinate_type<PointType>::type Unit;
  335. x(point, x(point) * (Unit)factor);
  336. y(point, y(point) * (Unit)factor);
  337. return point;
  338. }
  339. struct y_pt_scale_down : gtl_yes {};
  340. template <typename PointType, typename CType>
  341. typename enable_if<
  342. typename gtl_and<
  343. y_pt_scale_down,
  344. typename is_mutable_point_concept<
  345. typename geometry_concept<PointType>::type
  346. >::type
  347. >::type,
  348. PointType>::type& scale_down(PointType& point, CType factor) {
  349. typedef typename point_coordinate_type<PointType>::type Unit;
  350. typedef typename coordinate_traits<Unit>::coordinate_distance dt;
  351. x(point, scaling_policy<Unit>::round((dt)(x(point)) / (dt)factor));
  352. y(point, scaling_policy<Unit>::round((dt)(y(point)) / (dt)factor));
  353. return point;
  354. }
  355. struct y_pt_scale : gtl_yes {};
  356. template <typename PointType, typename ScaleType>
  357. typename enable_if<
  358. typename gtl_and<
  359. y_pt_scale,
  360. typename is_mutable_point_concept<
  361. typename geometry_concept<PointType>::type
  362. >::type
  363. >::type,
  364. PointType>::type& scale(PointType& point, const ScaleType& scaling) {
  365. typedef typename point_coordinate_type<PointType>::type Unit;
  366. Unit x_coord(x(point));
  367. Unit y_coord(y(point));
  368. scaling.scale(x_coord, y_coord);
  369. x(point, x_coord);
  370. y(point, y_coord);
  371. return point;
  372. }
  373. struct y_pt_transform : gtl_yes {};
  374. template <typename PointType, typename TransformType>
  375. typename enable_if<
  376. typename gtl_and<
  377. y_pt_transform,
  378. typename is_mutable_point_concept<
  379. typename geometry_concept<PointType>::type
  380. >::type
  381. >::type,
  382. PointType>::type& transform(PointType& point, const TransformType& transform) {
  383. typedef typename point_coordinate_type<PointType>::type Unit;
  384. Unit x_coord(x(point));
  385. Unit y_coord(y(point));
  386. transform.transform(x_coord, y_coord);
  387. x(point, x_coord);
  388. y(point, y_coord);
  389. return point;
  390. }
  391. struct y_pt_move : gtl_yes {};
  392. template <typename PointType>
  393. typename enable_if<
  394. typename gtl_and<
  395. y_pt_move,
  396. typename is_mutable_point_concept<
  397. typename geometry_concept<PointType>::type
  398. >::type
  399. >::type,
  400. PointType>::type& move(PointType& point, orientation_2d orient,
  401. typename point_coordinate_type<PointType>::type displacement) {
  402. typedef typename point_coordinate_type<PointType>::type Unit;
  403. Unit coord = get(point, orient);
  404. set(point, orient, coord + displacement);
  405. return point;
  406. }
  407. } // polygon
  408. } // boost
  409. #endif // BOOST_POLYGON_POINT_CONCEPT_HPP