gtl_custom_point.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. namespace gtl = boost::polygon;
  10. using namespace boost::polygon::operators;
  11. //lets make the body of main from point_usage.cpp
  12. //a generic function parameterized by point type
  13. template <typename Point>
  14. void test_point() {
  15. //constructing a gtl point
  16. int x = 10;
  17. int y = 20;
  18. //Point pt(x, y);
  19. Point pt = gtl::construct<Point>(x, y);
  20. assert(gtl::x(pt) == 10);
  21. assert(gtl::y(pt) == 20);
  22. //a quick primer in isotropic point access
  23. typedef gtl::orientation_2d O;
  24. using gtl::HORIZONTAL;
  25. using gtl::VERTICAL;
  26. O o = HORIZONTAL;
  27. assert(gtl::x(pt) == gtl::get(pt, o));
  28. o = o.get_perpendicular();
  29. assert(o == VERTICAL);
  30. assert(gtl::y(pt) == gtl::get(pt, o));
  31. gtl::set(pt, o, 30);
  32. assert(gtl::y(pt) == 30);
  33. //using some of the library functions
  34. //Point pt2(10, 30);
  35. Point pt2 = gtl::construct<Point>(10, 30);
  36. assert(gtl::equivalence(pt, pt2));
  37. gtl::transformation<int> tr(gtl::axis_transformation::SWAP_XY);
  38. gtl::transform(pt, tr);
  39. assert(gtl::equivalence(pt, gtl::construct<Point>(30, 10)));
  40. gtl::transformation<int> tr2 = tr.inverse();
  41. assert(tr == tr2); //SWAP_XY is its own inverse transform
  42. gtl::transform(pt, tr2);
  43. assert(gtl::equivalence(pt, pt2)); //the two points are equal again
  44. gtl::move(pt, o, 10); //move pt 10 units in y
  45. assert(gtl::euclidean_distance(pt, pt2) == 10.0f);
  46. gtl::move(pt, o.get_perpendicular(), 10); //move pt 10 units in x
  47. assert(gtl::manhattan_distance(pt, pt2) == 20);
  48. }
  49. //Now lets declare our own point type
  50. //Bjarne says that if a class doesn't maintain an
  51. //invariant just use a struct.
  52. struct CPoint {
  53. int x;
  54. int y;
  55. };
  56. //There, nice a simple...but wait, it doesn't do anything
  57. //how do we use it to do all the things a point needs to do?
  58. //First we register it as a point with boost polygon
  59. namespace boost { namespace polygon {
  60. template <>
  61. struct geometry_concept<CPoint> { typedef point_concept type; };
  62. //Then we specialize the gtl point traits for our point type
  63. template <>
  64. struct point_traits<CPoint> {
  65. typedef int coordinate_type;
  66. static inline coordinate_type get(const CPoint& point,
  67. orientation_2d orient) {
  68. if(orient == HORIZONTAL)
  69. return point.x;
  70. return point.y;
  71. }
  72. };
  73. template <>
  74. struct point_mutable_traits<CPoint> {
  75. typedef int coordinate_type;
  76. static inline void set(CPoint& point, orientation_2d orient, int value) {
  77. if(orient == HORIZONTAL)
  78. point.x = value;
  79. else
  80. point.y = value;
  81. }
  82. static inline CPoint construct(int x_value, int y_value) {
  83. CPoint retval;
  84. retval.x = x_value;
  85. retval.y = y_value;
  86. return retval;
  87. }
  88. };
  89. } }
  90. //Now lets see if the CPoint works with the library functions
  91. int main() {
  92. test_point<CPoint>(); //yay! All your testing is done for you.
  93. return 0;
  94. }
  95. //Now you know how to map a user type to the library point concept
  96. //and how to write a generic function parameterized by point type
  97. //using the library interfaces to access it.