gtl_custom_polygon.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. #include <boost/polygon/polygon.hpp>
  8. #include <cassert>
  9. #include <list>
  10. namespace gtl = boost::polygon;
  11. using namespace boost::polygon::operators;
  12. //first lets turn our polygon usage code into a generic
  13. //function parameterized by polygon type
  14. template <typename Polygon>
  15. void test_polygon() {
  16. //lets construct a 10x10 rectangle shaped polygon
  17. typedef typename gtl::polygon_traits<Polygon>::point_type Point;
  18. Point pts[] = {gtl::construct<Point>(0, 0),
  19. gtl::construct<Point>(10, 0),
  20. gtl::construct<Point>(10, 10),
  21. gtl::construct<Point>(0, 10) };
  22. Polygon poly;
  23. gtl::set_points(poly, pts, pts+4);
  24. //now lets see what we can do with this polygon
  25. assert(gtl::area(poly) == 100.0f);
  26. assert(gtl::contains(poly, gtl::construct<Point>(5, 5)));
  27. assert(!gtl::contains(poly, gtl::construct<Point>(15, 5)));
  28. gtl::rectangle_data<int> rect;
  29. assert(gtl::extents(rect, poly)); //get bounding box of poly
  30. assert(gtl::equivalence(rect, poly)); //hey, that's slick
  31. assert(gtl::winding(poly) == gtl::COUNTERCLOCKWISE);
  32. assert(gtl::perimeter(poly) == 40.0f);
  33. //add 5 to all coords of poly
  34. gtl::convolve(poly, gtl::construct<Point>(5, 5));
  35. //multiply all coords of poly by 2
  36. gtl::scale_up(poly, 2);
  37. gtl::set_points(rect, gtl::point_data<int>(10, 10),
  38. gtl::point_data<int>(30, 30));
  39. assert(gtl::equivalence(poly, rect));
  40. }
  41. //Now lets declare our own polygon class
  42. //Oops, we need a point class to support our polygon, lets borrow
  43. //the CPoint example
  44. struct CPoint {
  45. int x;
  46. int y;
  47. };
  48. //we have to get CPoint working with boost polygon to make our polygon
  49. //that uses CPoint working with boost polygon
  50. namespace boost { namespace polygon {
  51. template <>
  52. struct geometry_concept<CPoint> { typedef point_concept type; };
  53. template <>
  54. struct point_traits<CPoint> {
  55. typedef int coordinate_type;
  56. static inline coordinate_type get(const CPoint& point,
  57. orientation_2d orient) {
  58. if(orient == HORIZONTAL)
  59. return point.x;
  60. return point.y;
  61. }
  62. };
  63. template <>
  64. struct point_mutable_traits<CPoint> {
  65. typedef int coordinate_type;
  66. static inline void set(CPoint& point, orientation_2d orient, int value) {
  67. if(orient == HORIZONTAL)
  68. point.x = value;
  69. else
  70. point.y = value;
  71. }
  72. static inline CPoint construct(int x_value, int y_value) {
  73. CPoint retval;
  74. retval.x = x_value;
  75. retval.y = y_value;
  76. return retval;
  77. }
  78. };
  79. } }
  80. //I'm lazy and use the stl everywhere to avoid writing my own classes
  81. //my toy polygon is a std::list<CPoint>
  82. typedef std::list<CPoint> CPolygon;
  83. //we need to specialize our polygon concept mapping in boost polygon
  84. namespace boost { namespace polygon {
  85. //first register CPolygon as a polygon_concept type
  86. template <>
  87. struct geometry_concept<CPolygon>{ typedef polygon_concept type; };
  88. template <>
  89. struct polygon_traits<CPolygon> {
  90. typedef int coordinate_type;
  91. typedef CPolygon::const_iterator iterator_type;
  92. typedef CPoint point_type;
  93. // Get the begin iterator
  94. static inline iterator_type begin_points(const CPolygon& t) {
  95. return t.begin();
  96. }
  97. // Get the end iterator
  98. static inline iterator_type end_points(const CPolygon& t) {
  99. return t.end();
  100. }
  101. // Get the number of sides of the polygon
  102. static inline std::size_t size(const CPolygon& t) {
  103. return t.size();
  104. }
  105. // Get the winding direction of the polygon
  106. static inline winding_direction winding(const CPolygon& t) {
  107. return unknown_winding;
  108. }
  109. };
  110. template <>
  111. struct polygon_mutable_traits<CPolygon> {
  112. //expects stl style iterators
  113. template <typename iT>
  114. static inline CPolygon& set_points(CPolygon& t,
  115. iT input_begin, iT input_end) {
  116. t.clear();
  117. t.insert(t.end(), input_begin, input_end);
  118. return t;
  119. }
  120. };
  121. } }
  122. //now there's nothing left to do but test that our polygon
  123. //works with library interfaces
  124. int main() {
  125. test_polygon<CPolygon>(); //woot!
  126. return 0;
  127. }