123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- /*
- Copyright 2008 Intel Corporation
- Use, modification and distribution are subject to the Boost Software License,
- Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- http://www.boost.org/LICENSE_1_0.txt).
- */
- #include <boost/polygon/polygon.hpp>
- #include <cassert>
- namespace gtl = boost::polygon;
- using namespace boost::polygon::operators;
- //lets make the body of main from point_usage.cpp
- //a generic function parameterized by point type
- template <typename Point>
- void test_point() {
- //constructing a gtl point
- int x = 10;
- int y = 20;
- //Point pt(x, y);
- Point pt = gtl::construct<Point>(x, y);
- assert(gtl::x(pt) == 10);
- assert(gtl::y(pt) == 20);
-
- //a quick primer in isotropic point access
- typedef gtl::orientation_2d O;
- using gtl::HORIZONTAL;
- using gtl::VERTICAL;
- O o = HORIZONTAL;
- assert(gtl::x(pt) == gtl::get(pt, o));
-
- o = o.get_perpendicular();
- assert(o == VERTICAL);
- assert(gtl::y(pt) == gtl::get(pt, o));
-
- gtl::set(pt, o, 30);
- assert(gtl::y(pt) == 30);
-
- //using some of the library functions
- //Point pt2(10, 30);
- Point pt2 = gtl::construct<Point>(10, 30);
- assert(gtl::equivalence(pt, pt2));
-
- gtl::transformation<int> tr(gtl::axis_transformation::SWAP_XY);
- gtl::transform(pt, tr);
- assert(gtl::equivalence(pt, gtl::construct<Point>(30, 10)));
-
- gtl::transformation<int> tr2 = tr.inverse();
- assert(tr == tr2); //SWAP_XY is its own inverse transform
-
- gtl::transform(pt, tr2);
- assert(gtl::equivalence(pt, pt2)); //the two points are equal again
-
- gtl::move(pt, o, 10); //move pt 10 units in y
- assert(gtl::euclidean_distance(pt, pt2) == 10.0f);
-
- gtl::move(pt, o.get_perpendicular(), 10); //move pt 10 units in x
- assert(gtl::manhattan_distance(pt, pt2) == 20);
- }
-
- //Now lets declare our own point type
- //Bjarne says that if a class doesn't maintain an
- //invariant just use a struct.
- struct CPoint {
- int x;
- int y;
- };
-
- //There, nice a simple...but wait, it doesn't do anything
- //how do we use it to do all the things a point needs to do?
-
-
- //First we register it as a point with boost polygon
- namespace boost { namespace polygon {
- template <>
- struct geometry_concept<CPoint> { typedef point_concept type; };
-
-
- //Then we specialize the gtl point traits for our point type
- template <>
- struct point_traits<CPoint> {
- typedef int coordinate_type;
-
- static inline coordinate_type get(const CPoint& point,
- orientation_2d orient) {
- if(orient == HORIZONTAL)
- return point.x;
- return point.y;
- }
- };
-
- template <>
- struct point_mutable_traits<CPoint> {
- typedef int coordinate_type;
- static inline void set(CPoint& point, orientation_2d orient, int value) {
- if(orient == HORIZONTAL)
- point.x = value;
- else
- point.y = value;
- }
- static inline CPoint construct(int x_value, int y_value) {
- CPoint retval;
- retval.x = x_value;
- retval.y = y_value;
- return retval;
- }
- };
- } }
-
- //Now lets see if the CPoint works with the library functions
- int main() {
- test_point<CPoint>(); //yay! All your testing is done for you.
- return 0;
- }
-
- //Now you know how to map a user type to the library point concept
- //and how to write a generic function parameterized by point type
- //using the library interfaces to access it.
|