isotropy.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  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_ISOTROPY_HPP
  8. #define BOOST_POLYGON_ISOTROPY_HPP
  9. //external
  10. #include <cmath>
  11. #include <cstddef>
  12. #include <cstdlib>
  13. #include <vector>
  14. #include <deque>
  15. #include <map>
  16. #include <set>
  17. #include <list>
  18. //#include <iostream>
  19. #include <algorithm>
  20. #include <limits>
  21. #include <iterator>
  22. #include <string>
  23. #ifndef BOOST_POLYGON_NO_DEPS
  24. #include <boost/config.hpp>
  25. #ifdef BOOST_MSVC
  26. #define BOOST_POLYGON_MSVC
  27. #endif
  28. #ifdef BOOST_INTEL
  29. #define BOOST_POLYGON_ICC
  30. #endif
  31. #ifdef BOOST_HAS_LONG_LONG
  32. #define BOOST_POLYGON_USE_LONG_LONG
  33. typedef boost::long_long_type polygon_long_long_type;
  34. typedef boost::ulong_long_type polygon_ulong_long_type;
  35. //typedef long long polygon_long_long_type;
  36. //typedef unsigned long long polygon_ulong_long_type;
  37. #endif
  38. #include <boost/mpl/size_t.hpp>
  39. #include <boost/mpl/protect.hpp>
  40. #include <boost/utility/enable_if.hpp>
  41. #include <boost/mpl/bool.hpp>
  42. #include <boost/mpl/and.hpp>
  43. #include <boost/mpl/or.hpp>
  44. #else
  45. #ifdef _WIN32
  46. #define BOOST_POLYGON_MSVC
  47. #endif
  48. #ifdef __ICC
  49. #define BOOST_POLYGON_ICC
  50. #endif
  51. #define BOOST_POLYGON_USE_LONG_LONG
  52. typedef long long polygon_long_long_type;
  53. typedef unsigned long long polygon_ulong_long_type;
  54. namespace boost {
  55. template <bool B, class T = void>
  56. struct enable_if_c {
  57. typedef T type;
  58. };
  59. template <class T>
  60. struct enable_if_c<false, T> {};
  61. template <class Cond, class T = void>
  62. struct enable_if : public enable_if_c<Cond::value, T> {};
  63. template <bool B, class T>
  64. struct lazy_enable_if_c {
  65. typedef typename T::type type;
  66. };
  67. template <class T>
  68. struct lazy_enable_if_c<false, T> {};
  69. template <class Cond, class T>
  70. struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
  71. template <bool B, class T = void>
  72. struct disable_if_c {
  73. typedef T type;
  74. };
  75. template <class T>
  76. struct disable_if_c<true, T> {};
  77. template <class Cond, class T = void>
  78. struct disable_if : public disable_if_c<Cond::value, T> {};
  79. template <bool B, class T>
  80. struct lazy_disable_if_c {
  81. typedef typename T::type type;
  82. };
  83. template <class T>
  84. struct lazy_disable_if_c<true, T> {};
  85. template <class Cond, class T>
  86. struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
  87. }
  88. #endif
  89. namespace boost { namespace polygon{
  90. enum GEOMETRY_CONCEPT_ID {
  91. COORDINATE_CONCEPT,
  92. INTERVAL_CONCEPT,
  93. POINT_CONCEPT,
  94. POINT_3D_CONCEPT,
  95. RECTANGLE_CONCEPT,
  96. POLYGON_90_CONCEPT,
  97. POLYGON_90_WITH_HOLES_CONCEPT,
  98. POLYGON_45_CONCEPT,
  99. POLYGON_45_WITH_HOLES_CONCEPT,
  100. POLYGON_CONCEPT,
  101. POLYGON_WITH_HOLES_CONCEPT,
  102. POLYGON_90_SET_CONCEPT,
  103. POLYGON_45_SET_CONCEPT,
  104. POLYGON_SET_CONCEPT
  105. };
  106. struct undefined_concept {};
  107. template <typename T>
  108. struct geometry_concept { typedef undefined_concept type; };
  109. template <typename GCT, typename T>
  110. struct view_of {};
  111. template <typename T1, typename T2>
  112. view_of<T1, T2> view_as(const T2& obj) { return view_of<T1, T2>(obj); }
  113. template <typename T>
  114. struct coordinate_traits {};
  115. //used to override long double with an infinite precision datatype
  116. template <typename T>
  117. struct high_precision_type {
  118. typedef long double type;
  119. };
  120. template <typename T>
  121. T convert_high_precision_type(const typename high_precision_type<T>::type& v) {
  122. return T(v);
  123. }
  124. //used to override std::sort with an alternative (parallel) algorithm
  125. template <typename iter_type>
  126. void polygon_sort(iter_type _b_, iter_type _e_);
  127. template <typename iter_type, typename pred_type>
  128. void polygon_sort(iter_type _b_, iter_type _e_, const pred_type& _pred_);
  129. template <>
  130. struct coordinate_traits<int> {
  131. typedef int coordinate_type;
  132. typedef long double area_type;
  133. #ifdef BOOST_POLYGON_USE_LONG_LONG
  134. typedef polygon_long_long_type manhattan_area_type;
  135. typedef polygon_ulong_long_type unsigned_area_type;
  136. typedef polygon_long_long_type coordinate_difference;
  137. #else
  138. typedef long manhattan_area_type;
  139. typedef unsigned long unsigned_area_type;
  140. typedef long coordinate_difference;
  141. #endif
  142. typedef long double coordinate_distance;
  143. };
  144. #ifdef BOOST_POLYGON_USE_LONG_LONG
  145. template <>
  146. struct coordinate_traits<polygon_long_long_type> {
  147. typedef polygon_long_long_type coordinate_type;
  148. typedef long double area_type;
  149. typedef polygon_long_long_type manhattan_area_type;
  150. typedef polygon_ulong_long_type unsigned_area_type;
  151. typedef polygon_long_long_type coordinate_difference;
  152. typedef long double coordinate_distance;
  153. };
  154. #endif
  155. template <>
  156. struct coordinate_traits<float> {
  157. typedef float coordinate_type;
  158. typedef float area_type;
  159. typedef float manhattan_area_type;
  160. typedef float unsigned_area_type;
  161. typedef float coordinate_difference;
  162. typedef float coordinate_distance;
  163. };
  164. template <>
  165. struct coordinate_traits<double> {
  166. typedef double coordinate_type;
  167. typedef double area_type;
  168. typedef double manhattan_area_type;
  169. typedef double unsigned_area_type;
  170. typedef double coordinate_difference;
  171. typedef double coordinate_distance;
  172. };
  173. template <>
  174. struct coordinate_traits<long double> {
  175. typedef long double coordinate_type;
  176. typedef long double area_type;
  177. typedef long double manhattan_area_type;
  178. typedef long double unsigned_area_type;
  179. typedef long double coordinate_difference;
  180. typedef long double coordinate_distance;
  181. };
  182. template <typename T>
  183. struct scaling_policy {
  184. template <typename T2>
  185. static inline T round(T2 t2) {
  186. return (T)std::floor(t2+0.5);
  187. }
  188. static inline T round(T t2) {
  189. return t2;
  190. }
  191. };
  192. struct coordinate_concept {};
  193. template <>
  194. struct geometry_concept<int> { typedef coordinate_concept type; };
  195. #ifdef BOOST_POLYGON_USE_LONG_LONG
  196. template <>
  197. struct geometry_concept<polygon_long_long_type> { typedef coordinate_concept type; };
  198. #endif
  199. template <>
  200. struct geometry_concept<float> { typedef coordinate_concept type; };
  201. template <>
  202. struct geometry_concept<double> { typedef coordinate_concept type; };
  203. template <>
  204. struct geometry_concept<long double> { typedef coordinate_concept type; };
  205. #ifndef BOOST_POLYGON_NO_DEPS
  206. struct gtl_no : mpl::bool_<false> {};
  207. struct gtl_yes : mpl::bool_<true> {};
  208. template <typename T, typename T2>
  209. struct gtl_and : mpl::and_<T, T2> {};
  210. template <typename T, typename T2, typename T3>
  211. struct gtl_and_3 : mpl::and_<T, T2, T3> {};
  212. template <typename T, typename T2, typename T3, typename T4>
  213. struct gtl_and_4 : mpl::and_<T, T2, T3, T4> {};
  214. // template <typename T, typename T2>
  215. // struct gtl_or : mpl::or_<T, T2> {};
  216. // template <typename T, typename T2, typename T3>
  217. // struct gtl_or_3 : mpl::or_<T, T2, T3> {};
  218. // template <typename T, typename T2, typename T3, typename T4>
  219. // struct gtl_or_4 : mpl::or_<T, T2, T3, T4> {};
  220. #else
  221. struct gtl_no { static const bool value = false; };
  222. struct gtl_yes { typedef gtl_yes type;
  223. static const bool value = true; };
  224. template <bool T, bool T2>
  225. struct gtl_and_c { typedef gtl_no type; };
  226. template <>
  227. struct gtl_and_c<true, true> { typedef gtl_yes type; };
  228. template <typename T, typename T2>
  229. struct gtl_and : gtl_and_c<T::value, T2::value> {};
  230. template <typename T, typename T2, typename T3>
  231. struct gtl_and_3 { typedef typename gtl_and<
  232. T, typename gtl_and<T2, T3>::type>::type type; };
  233. template <typename T, typename T2, typename T3, typename T4>
  234. struct gtl_and_4 { typedef typename gtl_and_3<
  235. T, T2, typename gtl_and<T3, T4>::type>::type type; };
  236. #endif
  237. template <typename T, typename T2>
  238. struct gtl_or { typedef gtl_yes type; };
  239. template <typename T>
  240. struct gtl_or<T, T> { typedef T type; };
  241. template <typename T, typename T2, typename T3>
  242. struct gtl_or_3 { typedef typename gtl_or<
  243. T, typename gtl_or<T2, T3>::type>::type type; };
  244. template <typename T, typename T2, typename T3, typename T4>
  245. struct gtl_or_4 { typedef typename gtl_or<
  246. T, typename gtl_or_3<T2, T3, T4>::type>::type type; };
  247. template <typename T>
  248. struct gtl_not { typedef gtl_no type; };
  249. template <>
  250. struct gtl_not<gtl_no> { typedef gtl_yes type; };
  251. template <typename T>
  252. struct gtl_if {
  253. #ifdef BOOST_POLYGON_MSVC
  254. typedef gtl_no type;
  255. #endif
  256. };
  257. template <>
  258. struct gtl_if<gtl_yes> { typedef gtl_yes type; };
  259. template <typename T, typename T2>
  260. struct gtl_same_type { typedef gtl_no type; };
  261. template <typename T>
  262. struct gtl_same_type<T, T> { typedef gtl_yes type; };
  263. template <typename T, typename T2>
  264. struct gtl_different_type { typedef typename gtl_not<typename gtl_same_type<T, T2>::type>::type type; };
  265. struct manhattan_domain {};
  266. struct forty_five_domain {};
  267. struct general_domain {};
  268. template <typename T>
  269. struct geometry_domain { typedef general_domain type; };
  270. template <typename domain_type, typename coordinate_type>
  271. struct area_type_by_domain { typedef typename coordinate_traits<coordinate_type>::area_type type; };
  272. template <typename coordinate_type>
  273. struct area_type_by_domain<manhattan_domain, coordinate_type> {
  274. typedef typename coordinate_traits<coordinate_type>::manhattan_area_type type; };
  275. struct y_c_edist : gtl_yes {};
  276. template <typename coordinate_type_1, typename coordinate_type_2>
  277. typename enable_if<
  278. typename gtl_and_3<y_c_edist, typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type,
  279. typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type,
  280. typename coordinate_traits<coordinate_type_1>::coordinate_difference>::type
  281. euclidean_distance(const coordinate_type_1& lvalue, const coordinate_type_2& rvalue) {
  282. typedef typename coordinate_traits<coordinate_type_1>::coordinate_difference Unit;
  283. return (lvalue < rvalue) ? (Unit)rvalue - (Unit)lvalue : (Unit)lvalue - (Unit)rvalue;
  284. }
  285. // predicated_swap swaps a and b if pred is true
  286. // predicated_swap is guarenteed to behave the same as
  287. // if(pred){
  288. // T tmp = a;
  289. // a = b;
  290. // b = tmp;
  291. // }
  292. // but will not generate a branch instruction.
  293. // predicated_swap always creates a temp copy of a, but does not
  294. // create more than one temp copy of an input.
  295. // predicated_swap can be used to optimize away branch instructions in C++
  296. template <class T>
  297. inline bool predicated_swap(const bool& pred,
  298. T& a,
  299. T& b) {
  300. const T tmp = a;
  301. const T* input[2] = {&b, &tmp};
  302. a = *input[!pred];
  303. b = *input[pred];
  304. return pred;
  305. }
  306. enum direction_1d_enum { LOW = 0, HIGH = 1,
  307. LEFT = 0, RIGHT = 1,
  308. CLOCKWISE = 0, COUNTERCLOCKWISE = 1,
  309. REVERSE = 0, FORWARD = 1,
  310. NEGATIVE = 0, POSITIVE = 1 };
  311. enum orientation_2d_enum { HORIZONTAL = 0, VERTICAL = 1 };
  312. enum direction_2d_enum { WEST = 0, EAST = 1, SOUTH = 2, NORTH = 3 };
  313. enum orientation_3d_enum { PROXIMAL = 2 };
  314. enum direction_3d_enum { DOWN = 4, UP = 5 };
  315. enum winding_direction {
  316. clockwise_winding = 0,
  317. counterclockwise_winding = 1,
  318. unknown_winding = 2
  319. };
  320. class direction_2d;
  321. class direction_3d;
  322. class orientation_2d;
  323. class direction_1d {
  324. private:
  325. unsigned int val_;
  326. explicit direction_1d(int d);
  327. public:
  328. inline direction_1d() : val_(LOW) {}
  329. inline direction_1d(const direction_1d& that) : val_(that.val_) {}
  330. inline direction_1d(const direction_1d_enum val) : val_(val) {}
  331. explicit inline direction_1d(const direction_2d& that);
  332. explicit inline direction_1d(const direction_3d& that);
  333. inline direction_1d& operator = (const direction_1d& d) {
  334. val_ = d.val_; return * this; }
  335. inline bool operator==(direction_1d d) const { return (val_ == d.val_); }
  336. inline bool operator!=(direction_1d d) const { return !((*this) == d); }
  337. inline unsigned int to_int(void) const { return val_; }
  338. inline direction_1d& backward() { val_ ^= 1; return *this; }
  339. inline int get_sign() const { return val_ * 2 - 1; }
  340. };
  341. class direction_2d;
  342. class orientation_2d {
  343. private:
  344. unsigned int val_;
  345. explicit inline orientation_2d(int o);
  346. public:
  347. inline orientation_2d() : val_(HORIZONTAL) {}
  348. inline orientation_2d(const orientation_2d& ori) : val_(ori.val_) {}
  349. inline orientation_2d(const orientation_2d_enum val) : val_(val) {}
  350. explicit inline orientation_2d(const direction_2d& that);
  351. inline orientation_2d& operator=(const orientation_2d& ori) {
  352. val_ = ori.val_; return * this; }
  353. inline bool operator==(orientation_2d that) const { return (val_ == that.val_); }
  354. inline bool operator!=(orientation_2d that) const { return (val_ != that.val_); }
  355. inline unsigned int to_int() const { return (val_); }
  356. inline void turn_90() { val_ = val_^ 1; }
  357. inline orientation_2d get_perpendicular() const {
  358. orientation_2d retval = *this;
  359. retval.turn_90();
  360. return retval;
  361. }
  362. inline direction_2d get_direction(direction_1d dir) const;
  363. };
  364. class direction_2d {
  365. private:
  366. int val_;
  367. public:
  368. inline direction_2d() : val_(WEST) {}
  369. inline direction_2d(const direction_2d& that) : val_(that.val_) {}
  370. inline direction_2d(const direction_2d_enum val) : val_(val) {}
  371. inline direction_2d& operator=(const direction_2d& d) {
  372. val_ = d.val_;
  373. return * this;
  374. }
  375. inline ~direction_2d() { }
  376. inline bool operator==(direction_2d d) const { return (val_ == d.val_); }
  377. inline bool operator!=(direction_2d d) const { return !((*this) == d); }
  378. inline bool operator< (direction_2d d) const { return (val_ < d.val_); }
  379. inline bool operator<=(direction_2d d) const { return (val_ <= d.val_); }
  380. inline bool operator> (direction_2d d) const { return (val_ > d.val_); }
  381. inline bool operator>=(direction_2d d) const { return (val_ >= d.val_); }
  382. // Casting to int
  383. inline unsigned int to_int(void) const { return val_; }
  384. inline direction_2d backward() const {
  385. // flip the LSB, toggles 0 - 1 and 2 - 3
  386. return direction_2d(direction_2d_enum(val_ ^ 1));
  387. }
  388. // Returns a direction 90 degree left (LOW) or right(HIGH) to this one
  389. inline direction_2d turn(direction_1d t) const {
  390. return direction_2d(direction_2d_enum(val_ ^ 3 ^ (val_ >> 1) ^ t.to_int()));
  391. }
  392. // Returns a direction 90 degree left to this one
  393. inline direction_2d left() const {return turn(HIGH);}
  394. // Returns a direction 90 degree right to this one
  395. inline direction_2d right() const {return turn(LOW);}
  396. // N, E are positive, S, W are negative
  397. inline bool is_positive() const {return (val_ & 1);}
  398. inline bool is_negative() const {return !is_positive();}
  399. inline int get_sign() const {return ((is_positive()) << 1) -1;}
  400. };
  401. direction_1d::direction_1d(const direction_2d& that) : val_(that.to_int() & 1) {}
  402. orientation_2d::orientation_2d(const direction_2d& that) : val_(that.to_int() >> 1) {}
  403. direction_2d orientation_2d::get_direction(direction_1d dir) const {
  404. return direction_2d(direction_2d_enum((val_ << 1) + dir.to_int()));
  405. }
  406. class orientation_3d {
  407. private:
  408. unsigned int val_;
  409. explicit inline orientation_3d(int o);
  410. public:
  411. inline orientation_3d() : val_((int)HORIZONTAL) {}
  412. inline orientation_3d(const orientation_3d& ori) : val_(ori.val_) {}
  413. inline orientation_3d(orientation_2d ori) : val_(ori.to_int()) {}
  414. inline orientation_3d(const orientation_3d_enum val) : val_(val) {}
  415. explicit inline orientation_3d(const direction_2d& that);
  416. explicit inline orientation_3d(const direction_3d& that);
  417. inline ~orientation_3d() { }
  418. inline orientation_3d& operator=(const orientation_3d& ori) {
  419. val_ = ori.val_; return * this; }
  420. inline bool operator==(orientation_3d that) const { return (val_ == that.val_); }
  421. inline bool operator!=(orientation_3d that) const { return (val_ != that.val_); }
  422. inline unsigned int to_int() const { return (val_); }
  423. inline direction_3d get_direction(direction_1d dir) const;
  424. };
  425. class direction_3d {
  426. private:
  427. int val_;
  428. public:
  429. inline direction_3d() : val_(WEST) {}
  430. inline direction_3d(direction_2d that) : val_(that.to_int()) {}
  431. inline direction_3d(const direction_3d& that) : val_(that.val_) {}
  432. inline direction_3d(const direction_2d_enum val) : val_(val) {}
  433. inline direction_3d(const direction_3d_enum val) : val_(val) {}
  434. inline direction_3d& operator=(direction_3d d) {
  435. val_ = d.val_;
  436. return * this;
  437. }
  438. inline ~direction_3d() { }
  439. inline bool operator==(direction_3d d) const { return (val_ == d.val_); }
  440. inline bool operator!=(direction_3d d) const { return !((*this) == d); }
  441. inline bool operator< (direction_3d d) const { return (val_ < d.val_); }
  442. inline bool operator<=(direction_3d d) const { return (val_ <= d.val_); }
  443. inline bool operator> (direction_3d d) const { return (val_ > d.val_); }
  444. inline bool operator>=(direction_3d d) const { return (val_ >= d.val_); }
  445. // Casting to int
  446. inline unsigned int to_int(void) const { return val_; }
  447. inline direction_3d backward() const {
  448. // flip the LSB, toggles 0 - 1 and 2 - 3 and 4 - 5
  449. return direction_2d(direction_2d_enum(val_ ^ 1));
  450. }
  451. // N, E, U are positive, S, W, D are negative
  452. inline bool is_positive() const {return (val_ & 1);}
  453. inline bool is_negative() const {return !is_positive();}
  454. inline int get_sign() const {return ((is_positive()) << 1) -1;}
  455. };
  456. direction_1d::direction_1d(const direction_3d& that) : val_(that.to_int() & 1) {}
  457. orientation_3d::orientation_3d(const direction_3d& that) : val_(that.to_int() >> 1) {}
  458. orientation_3d::orientation_3d(const direction_2d& that) : val_(that.to_int() >> 1) {}
  459. direction_3d orientation_3d::get_direction(direction_1d dir) const {
  460. return direction_3d(direction_3d_enum((val_ << 1) + dir.to_int()));
  461. }
  462. }
  463. }
  464. #endif