Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r59798 - in sandbox/gtl/boost/polygon: . detail
From: lucanus.j.simonson_at_[hidden]
Date: 2010-02-20 19:15:40


Author: ljsimons
Date: 2010-02-20 19:15:39 EST (Sat, 20 Feb 2010)
New Revision: 59798
URL: http://svn.boost.org/trac/boost/changeset/59798

Log:
adding offsetting for general polygons
Text files modified:
   sandbox/gtl/boost/polygon/detail/polygon_arbitrary_formation.hpp | 114 +++---------
   sandbox/gtl/boost/polygon/detail/scan_arbitrary.hpp | 28 +-
   sandbox/gtl/boost/polygon/gtl_boost_unit_test.cpp | 356 ++++++++++++++++++++-------------------
   sandbox/gtl/boost/polygon/polygon_traits.hpp | 72 ++++++-
   4 files changed, 283 insertions(+), 287 deletions(-)

Modified: sandbox/gtl/boost/polygon/detail/polygon_arbitrary_formation.hpp
==============================================================================
--- sandbox/gtl/boost/polygon/detail/polygon_arbitrary_formation.hpp (original)
+++ sandbox/gtl/boost/polygon/detail/polygon_arbitrary_formation.hpp 2010-02-20 19:15:39 EST (Sat, 20 Feb 2010)
@@ -385,96 +385,33 @@
       };
     }
 
- //slower but more overflow protected way to compute coordinate of intersection
- template <typename product_type>
- static inline Unit compute_x_intercept(product_type x11,
- product_type x21,
- product_type y11,
- product_type y21,
- product_type dy1,
- product_type dy2,
- product_type dx1,
- product_type dx2) {
- // x = (x11 * dy1 * dx2 - x21 * dy2 * dx1 + y21 * dx1 * dx2 - y11 * dx1 * dx2) / (dy1 * dx2 - dy2 * dx1);
- typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type;
- unsigned_product_type udy1 = dy1 < 0 ? -dy1 : dy1;
- int dy1sign = dy1 < 0 ? -1 : 1;
- unsigned_product_type udy2 = dy2 < 0 ? -dy2 : dy2;
- int dy2sign = dy2 < 0 ? -1 : 1;
- unsigned_product_type udx1 = dx1 < 0 ? -dx1 : dx1;
- int dx1sign = dx1 < 0 ? -1 : 1;
- unsigned_product_type udx2 = dx2 < 0 ? -dx2 : dx2;
- int dx2sign = dx2 < 0 ? -1 : 1;
- unsigned_product_type u_dy1dx2 = udy1 * udx2;
- unsigned_product_type u_dy2dx1 = udy2 * udx1;
- unsigned_product_type u_dx1dx2 = udx1 * udx2;
- int dy1dx2sign = dy1sign * dx2sign;
- int dy2dx1sign = dy2sign * dx1sign;
- int dx1dx2sign = dx1sign * dx2sign;
- unsigned_product_type u_den = 0;;
- int den_sign = 0;;
- unsigned_add(u_den, den_sign, u_dy1dx2, dy1dx2sign, u_dy2dx1, -dy2dx1sign);
- product_type dy1dx2_q = u_dy1dx2 / u_den;
- product_type dy2dx1_q = u_dy2dx1 / u_den;
- product_type dx1dx2_q = u_dx1dx2 / u_den;
- dy1dx2_q *= dy1dx2sign * den_sign;
- dy2dx1_q *= dy2dx1sign * den_sign;
- dx1dx2_q *= dx1dx2sign * den_sign;
- unsigned_product_type u_dy1dx2_r = 0;;
- unsigned_product_type u_dy2dx1_r = 0;;
- unsigned_product_type u_dx1dx2_r = 0;;
- int dy1dx2_r_sign = 0;
- int dy2dx1_r_sign = 0;
- int dx1dx2_r_sign = 0;
- unsigned_mod(u_dy1dx2_r, dy1dx2_r_sign, u_dy1dx2, dy1dx2sign, u_den, den_sign);
- unsigned_mod(u_dy2dx1_r, dy2dx1_r_sign, u_dy2dx1, dy2dx1sign, u_den, den_sign);
- unsigned_mod(u_dx1dx2_r, dx1dx2_r_sign, u_dx1dx2, dx1dx2sign, u_den, den_sign);
- product_type dy1dx2_r = u_dy1dx2_r;
- product_type dy2dx1_r = u_dy2dx1_r;
- product_type dx1dx2_r = u_dx1dx2_r;
- dy1dx2_r *= dy1dx2_r_sign;
- dy2dx1_r *= dy2dx1_r_sign;
- dx1dx2_r *= dx1dx2_r_sign;
- product_type q = x11 * dy1dx2_q - x21 * dy2dx1_q + (y21 - y11) * dx1dx2_q;
- product_type r = x11 * dy1dx2_r - x21 * dy2dx1_r + (y21 - y11) * dx1dx2_r;
- unsigned_product_type ur = 0;
- int rsign = 0;;
- if(r < 0) { ur = -r; rsign = -1; } else { ur = r; rsign = 1; }
- //this operation performs only one truncation
- ur /= u_den;
- rsign *= den_sign;
- r = ur;
- r *= rsign;
- return q + r;
- }
-
     struct compute_intersection_pack {
       typedef typename high_precision_type<Unit>::type high_precision;
       high_precision y_high, dx1, dy1, dx2, dy2, x11, x21, y11, y21, x_num, y_num, x_den, y_den, x, y;
- static inline bool compute_lazy_intersection(Point& intersection, const half_edge& he1, const half_edge& he2) {
+ static inline bool compute_lazy_intersection(Point& intersection, const half_edge& he1, const half_edge& he2, bool projected = false) {
         long double y_high, dx1, dy1, dx2, dy2, x11, x21, y11, y21, x_num, y_num, x_den, y_den, x, y;
         typedef rectangle_data<Unit> Rectangle;
         Rectangle rect1, rect2;
         set_points(rect1, he1.first, he1.second);
         set_points(rect2, he2.first, he2.second);
- if(!::boost::polygon::intersects(rect1, rect2, true)) return false;
+ if(!projected && !::boost::polygon::intersects(rect1, rect2, true)) return false;
         if(is_vertical(he1)) {
           if(is_vertical(he2)) return false;
           y_high = evalAtXforYlazy(he1.first.get(HORIZONTAL), he2.first, he2.second);
- Unit y = (Unit)y_high;
- if(y_high < y) --y;
- if(contains(rect1.get(VERTICAL), y, true)) {
- intersection = Point(he1.first.get(HORIZONTAL), y);
+ Unit y_local = (Unit)y_high;
+ if(y_high < y_local) --y_local;
+ if(projected || contains(rect1.get(VERTICAL), y_local, true)) {
+ intersection = Point(he1.first.get(HORIZONTAL), y_local);
             return true;
           } else {
             return false;
           }
         } else if(is_vertical(he2)) {
           y_high = evalAtXforYlazy(he2.first.get(HORIZONTAL), he1.first, he1.second);
- Unit y = (Unit)y_high;
- if(y_high < y) --y;
- if(contains(rect2.get(VERTICAL), y, true)) {
- intersection = Point(he2.first.get(HORIZONTAL), y);
+ Unit y_local = (Unit)y_high;
+ if(y_high < y_local) --y_local;
+ if(projected || contains(rect2.get(VERTICAL), y_local, true)) {
+ intersection = Point(he2.first.get(HORIZONTAL), y_local);
             return true;
           } else {
             return false;
@@ -519,18 +456,30 @@
         //Unit y2 = evalAtXforY(exp_x, he2.first, he2.second);
         //std::cout << exp_x << " " << exp_y << " " << y1 << " " << y2 << std::endl;
         Point result(x_unit, y_unit);
- if(!contains(rect1, result, true)) return false;
- if(!contains(rect2, result, true)) return false;
+ if(!projected && !contains(rect1, result, true)) return false;
+ if(!projected && !contains(rect2, result, true)) return false;
         intersection = result;
         return true;
       }
- inline bool compute_intersection(Point& intersection, const half_edge& he1, const half_edge& he2) {
- if(!intersects(he1, he2))
+ inline bool compute_intersection(Point& intersection, const half_edge& he1, const half_edge& he2, bool projected = false) {
+ if(!projected && !intersects(he1, he2))
            return false;
- compute_lazy_intersection(intersection, he1, he2);
- if(intersects_grid(intersection, he1) &&
- intersects_grid(intersection, he2))
- return true;
+ bool lazy_success = compute_lazy_intersection(intersection, he1, he2, projected);
+ if(!projected) {
+ if(lazy_success) {
+ if(intersects_grid(intersection, he1) &&
+ intersects_grid(intersection, he2))
+ return true;
+ }
+ } else {
+ if(lazy_success) {
+ rectangle_data<Unit> inf_rect((std::numeric_limits<Unit>::min)(), (std::numeric_limits<Unit>::min)(),
+ (std::numeric_limits<Unit>::max)(), (std::numeric_limits<Unit>::max)() );
+ return contains(inf_rect, intersection, true);
+ } else {
+ return false;
+ }
+ }
         typedef rectangle_data<Unit> Rectangle;
         Rectangle rect1, rect2;
         set_points(rect1, he1.first, he1.second);
@@ -768,7 +717,7 @@
       inline bool operator>(const vertex_half_edge& vertex) const { return vertex < (*this); }
       inline bool operator<=(const vertex_half_edge& vertex) const { return !((*this) > vertex); }
       inline bool operator>=(const vertex_half_edge& vertex) const { return !((*this) < vertex); }
- inline high_precision evalAtX(Unit xIn) const { return evalAtXforY(xIn, pt, other_pt); }
+ inline high_precision evalAtX(Unit xIn) const { return evalAtXforYlazy(xIn, pt, other_pt); }
       inline bool is_vertical() const {
         return pt.get(HORIZONTAL) == other_pt.get(HORIZONTAL);
       }
@@ -2277,6 +2226,7 @@
     inline trapezoid_arbitrary_formation(const trapezoid_arbitrary_formation& that) : polygon_arbitrary_formation<Unit>(that) {}
     inline trapezoid_arbitrary_formation& operator=(const trapezoid_arbitrary_formation& that) {
       * static_cast<polygon_arbitrary_formation<Unit>*>(this) = * static_cast<polygon_arbitrary_formation<Unit>*>(&that);
+ return *this;
     }
    
     //cT is an output container of Polygon45 or Polygon45WithHoles

Modified: sandbox/gtl/boost/polygon/detail/scan_arbitrary.hpp
==============================================================================
--- sandbox/gtl/boost/polygon/detail/scan_arbitrary.hpp (original)
+++ sandbox/gtl/boost/polygon/detail/scan_arbitrary.hpp 2010-02-20 19:15:39 EST (Sat, 20 Feb 2010)
@@ -985,12 +985,12 @@
     typename scanline_base<Unit>::evalAtXforYPack evalAtXforYPack_;
   public:
     inline scanline() : scan_data_(), removal_set_(), insertion_set_(), end_point_queue_(),
- x_((std::numeric_limits<Unit>::max)()), y_((std::numeric_limits<Unit>::max)()), just_before_(false) {
+ x_((std::numeric_limits<Unit>::max)()), y_((std::numeric_limits<Unit>::max)()), just_before_(false), evalAtXforYPack_() {
       less_half_edge lessElm(&x_, &just_before_, &evalAtXforYPack_);
       scan_data_ = scanline_type(lessElm);
     }
     inline scanline(const scanline& that) : scan_data_(), removal_set_(), insertion_set_(), end_point_queue_(),
- x_((std::numeric_limits<Unit>::max)()), y_((std::numeric_limits<Unit>::max)()), just_before_(false) {
+ x_((std::numeric_limits<Unit>::max)()), y_((std::numeric_limits<Unit>::max)()), just_before_(false), evalAtXforYPack_() {
       (*this) = that; }
     inline scanline& operator=(const scanline& that) {
       x_ = that.x_;
@@ -1512,7 +1512,7 @@
     class less_vertex_data {
       typename scanline_base<Unit>::evalAtXforYPack* pack_;
     public:
- less_vertex_data() {}
+ less_vertex_data() : pack_() {}
       less_vertex_data(typename scanline_base<Unit>::evalAtXforYPack* pack) : pack_(pack) {}
       bool operator()(const vertex_data_type& lvalue, const vertex_data_type& rvalue) {
         less_point lp;
@@ -1532,8 +1532,8 @@
     }
   public:
     inline property_merge_data& get_property_merge_data() { return pmd; }
- inline property_merge() : pmd() {}
- inline property_merge(const property_merge& pm) : pmd(pm.pmd) {}
+ inline property_merge() : pmd(), evalAtXforYPack_() {}
+ inline property_merge(const property_merge& pm) : pmd(pm.pmd), evalAtXforYPack_(pm.evalAtXforYPack_) {}
     inline property_merge& operator=(const property_merge& pm) { pmd = pm.pmd; return *this; }
 
     template <typename polygon_type>
@@ -2512,7 +2512,7 @@
     class less_vertex_data {
       typename scanline_base<Unit>::evalAtXforYPack* pack_;
     public:
- less_vertex_data() {}
+ less_vertex_data() : pack_() {}
       less_vertex_data(typename scanline_base<Unit>::evalAtXforYPack* pack) : pack_(pack) {}
       bool operator()(const vertex_data_type& lvalue, const vertex_data_type& rvalue) {
         less_point lp;
@@ -2583,8 +2583,8 @@
       std::sort(pmd.begin(), pmd.end(), lvd);
     }
   public:
- inline arbitrary_boolean_op() : pmd() {}
- inline arbitrary_boolean_op(const arbitrary_boolean_op& pm) : pmd(pm.pmd) {}
+ inline arbitrary_boolean_op() : pmd(), evalAtXforYPack_() {}
+ inline arbitrary_boolean_op(const arbitrary_boolean_op& pm) : pmd(pm.pmd), evalAtXforYPack_(pm.evalAtXforYPack_) {}
     inline arbitrary_boolean_op& operator=(const arbitrary_boolean_op& pm) { pmd = pm.pmd; return *this; }
 
     enum BOOLEAN_OP_TYPE {
@@ -2606,6 +2606,8 @@
       property_merge<Unit, property_type, std::vector<property_type> >::print(debug_file, pmd);
       debug_file.close();
 #endif
+ if(pmd.empty())
+ return;
       line_intersection<Unit>::validate_scan(tmp_pmd, pmd.begin(), pmd.end());
       pmd.swap(tmp_pmd);
       sort_property_merge_data();
@@ -2728,7 +2730,7 @@
     class less_vertex_data {
       typename scanline_base<Unit>::evalAtXforYPack* pack_;
     public:
- less_vertex_data() {}
+ less_vertex_data() : pack_() {}
       less_vertex_data(typename scanline_base<Unit>::evalAtXforYPack* pack) : pack_(pack) {}
       bool operator()(const vertex_data_type& lvalue, const vertex_data_type& rvalue) {
         less_point lp;
@@ -2749,9 +2751,9 @@
       Unit x = output.first.first;
       for(typename std::map<point_data<Unit>, std::set<property_type> >::iterator itr =
             y_prop_map.begin(); itr != y_prop_map.end(); ++itr) {
- if((*itr).first.x() != x) {
+ if((*itr).first.x() < x) {
           y_prop_map.erase(y_prop_map.begin(), itr);
- break;
+ continue;
         }
         for(typename std::set<property_type>::iterator inner_itr = itr->second.begin();
             inner_itr != itr->second.end(); ++inner_itr) {
@@ -2805,9 +2807,9 @@
       std::sort(pmd.begin(), pmd.end(), lvd);
     }
   public:
- inline arbitrary_connectivity_extraction() : pmd() {}
+ inline arbitrary_connectivity_extraction() : pmd(), evalAtXforYPack_() {}
     inline arbitrary_connectivity_extraction
- (const arbitrary_connectivity_extraction& pm) : pmd(pm.pmd) {}
+ (const arbitrary_connectivity_extraction& pm) : pmd(pm.pmd), evalAtXforYPack_(pm.evalAtXforYPack_) {}
     inline arbitrary_connectivity_extraction& operator=
       (const arbitrary_connectivity_extraction& pm) { pmd = pm.pmd; return *this; }
 

Modified: sandbox/gtl/boost/polygon/gtl_boost_unit_test.cpp
==============================================================================
--- sandbox/gtl/boost/polygon/gtl_boost_unit_test.cpp (original)
+++ sandbox/gtl/boost/polygon/gtl_boost_unit_test.cpp 2010-02-20 19:15:39 EST (Sat, 20 Feb 2010)
@@ -7,8 +7,10 @@
 */
 #define BOOST_POLYGON_NO_DEPS
 #include <iostream>
+#define BOOST_VERY_LITTLE_SFINAE
 //#include <boost/polygon/polygon.hpp>
 #include "polygon.hpp"
+//#include "ac_int_override.hpp"
 namespace gtl = boost::polygon;
 using namespace boost::polygon::operators;
 #include <time.h>
@@ -16,11 +18,11 @@
 
 namespace boost { namespace polygon{
 
-template <class T>
-std::ostream& operator << (std::ostream& o, const interval_data<T>& i)
-{
- return o << i.get(LOW) << ' ' << i.get(HIGH);
-}
+ template <class T>
+ std::ostream& operator << (std::ostream& o, const interval_data<T>& i)
+ {
+ return o << i.get(LOW) << ' ' << i.get(HIGH);
+ }
   template <class T>
   std::ostream& operator << (std::ostream& o, const point_data<T>& r)
   {
@@ -58,53 +60,53 @@
     //TODO
     return i;
   }
-template <typename T>
-std::ostream& operator << (std::ostream& o, const polygon_90_data<T>& r)
-{
- o << "Polygon { ";
- for(typename polygon_90_data<T>::iterator_type itr = r.begin(); itr != r.end(); ++itr) {
- o << *itr << ", ";
- }
- return o << "} ";
-}
-
-template <typename T>
-std::istream& operator >> (std::istream& i, polygon_90_data<T>& r)
-{
- std::size_t size;
- i >> size;
- std::vector<T> vec;
- vec.reserve(size);
- for(std::size_t ii = 0; ii < size; ++ii) {
- T coord;
- i >> coord;
- vec.push_back(coord);
+ template <typename T>
+ std::ostream& operator << (std::ostream& o, const polygon_90_data<T>& r)
+ {
+ o << "Polygon { ";
+ for(typename polygon_90_data<T>::iterator_type itr = r.begin(); itr != r.end(); ++itr) {
+ o << *itr << ", ";
+ }
+ return o << "} ";
+ }
+
+ template <typename T>
+ std::istream& operator >> (std::istream& i, polygon_90_data<T>& r)
+ {
+ std::size_t size;
+ i >> size;
+ std::vector<T> vec;
+ vec.reserve(size);
+ for(std::size_t ii = 0; ii < size; ++ii) {
+ T coord;
+ i >> coord;
+ vec.push_back(coord);
+ }
+ r.set_compact(vec.begin(), vec.end());
+ return i;
   }
- r.set_compact(vec.begin(), vec.end());
- return i;
-}
   
-template <typename T>
-std::ostream& operator << (std::ostream& o, const std::vector<polygon_90_data<T> >& r) {
- o << r.size() << ' ';
- for(std::size_t ii = 0; ii < r.size(); ++ii) {
- o << (r[ii]);
- }
- return o;
-}
-template <typename T>
-std::istream& operator >> (std::istream& i, std::vector<polygon_90_data<T> >& r) {
- std::size_t size;
- i >> size;
- r.clear();
- r.reserve(size);
- for(std::size_t ii = 0; ii < size; ++ii) {
- polygon_90_data<T> tmp;
- i >> tmp;
- r.push_back(tmp);
+ template <typename T>
+ std::ostream& operator << (std::ostream& o, const std::vector<polygon_90_data<T> >& r) {
+ o << r.size() << ' ';
+ for(std::size_t ii = 0; ii < r.size(); ++ii) {
+ o << (r[ii]);
+ }
+ return o;
+ }
+ template <typename T>
+ std::istream& operator >> (std::istream& i, std::vector<polygon_90_data<T> >& r) {
+ std::size_t size;
+ i >> size;
+ r.clear();
+ r.reserve(size);
+ for(std::size_t ii = 0; ii < size; ++ii) {
+ polygon_90_data<T> tmp;
+ i >> tmp;
+ r.push_back(tmp);
+ }
+ return i;
   }
- return i;
-}
   template <typename T>
   std::ostream& operator<<(std::ostream& o, const polygon_data<T>& poly) {
     o << "Polygon { ";
@@ -171,11 +173,11 @@
     o << " } } ";
     return o;
   }
-template <class T>
-std::ostream& operator << (std::ostream& o, const rectangle_data<T>& r)
-{
- return o << r.get(HORIZONTAL) << ' ' << r.get(VERTICAL);
-}
+ template <class T>
+ std::ostream& operator << (std::ostream& o, const rectangle_data<T>& r)
+ {
+ return o << r.get(HORIZONTAL) << ' ' << r.get(VERTICAL);
+ }
 
 
   template <typename T>
@@ -184,130 +186,130 @@
   template <typename T>
   typename enable_if<typename is_mutable_polygon_90_set_type<T>::type, void>::type
   print_is_mutable_polygon_90_set_concept(const T& ) { std::cout << "is mutable polygon 90 set concept\n"; }
-namespace boolean_op {
- //self contained unit test for BooleanOr algorithm
- template <typename Unit>
- inline bool testBooleanOr() {
- BooleanOp<int, Unit> booleanOr;
- //test one rectangle
- std::vector<std::pair<interval_data<Unit>, int> > container;
- booleanOr.processInterval(container, interval_data<Unit>(0, 10), 1);
- booleanOr.advanceScan();
- booleanOr.processInterval(container, interval_data<Unit>(0, 10), -1);
- if(container.size() != 2) {
- std::cout << "Test one rectangle, wrong output size\n";
- return false;
- }
- if(container[0] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), 1)) {
- std::cout << "Test one rectangle, first output wrong: Interval(" <<
- container[0].first << "), " << container[0].second << std::endl;
- }
- if(container[1] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), -1)) {
- std::cout << "Test one rectangle, second output wrong: Interval(" <<
- container[1].first << "), " << container[1].second << std::endl;
- }
-
- //test two rectangles
- container.clear();
- booleanOr = BooleanOp<int, Unit>();
- booleanOr.processInterval(container, interval_data<Unit>(0, 10), 1);
- booleanOr.advanceScan();
- booleanOr.processInterval(container, interval_data<Unit>(5, 15), 1);
- booleanOr.advanceScan();
- booleanOr.processInterval(container, interval_data<Unit>(0, 10), -1);
- booleanOr.advanceScan();
- booleanOr.processInterval(container, interval_data<Unit>(5, 15), -1);
- if(container.size() != 4) {
- std::cout << "Test two rectangles, wrong output size\n";
- for(std::size_t i = 0; i < container.size(); ++i){
- std::cout << container[i].first << "), " << container[i].second << std::endl;
- }
- return false;
- }
- if(container[0] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), 1)) {
- std::cout << "Test two rectangles, first output wrong: Interval(" <<
- container[0].first << "), " << container[0].second << std::endl;
- }
- if(container[1] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(10, 15), 1)) {
- std::cout << "Test two rectangles, second output wrong: Interval(" <<
- container[1].first << "), " << container[1].second << std::endl;
- }
- if(container[2] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 5), -1)) {
- std::cout << "Test two rectangles, third output wrong: Interval(" <<
- container[2].first << "), " << container[2].second << std::endl;
- }
- if(container[3] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(5, 15), -1)) {
- std::cout << "Test two rectangles, fourth output wrong: Interval(" <<
- container[3].first << "), " << container[3].second << std::endl;
- }
-
- //test two rectangles
- container.clear();
- booleanOr = BooleanOp<int, Unit>();
- booleanOr.processInterval(container, interval_data<Unit>(5, 15), 1);
- booleanOr.advanceScan();
- booleanOr.processInterval(container, interval_data<Unit>(0, 10), 1);
- booleanOr.advanceScan();
- booleanOr.processInterval(container, interval_data<Unit>(5, 15), -1);
- booleanOr.advanceScan();
- booleanOr.processInterval(container, interval_data<Unit>(0, 10), -1);
- if(container.size() != 4) {
- std::cout << "Test other two rectangles, wrong output size\n";
- for(std::size_t i = 0; i < container.size(); ++i){
- std::cout << container[i].first << "), " << container[i].second << std::endl;
- }
- return false;
- }
- if(container[0] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(5, 15), 1)) {
- std::cout << "Test other two rectangles, first output wrong: Interval(" <<
- container[0].first << "), " << container[0].second << std::endl;
- }
- if(container[1] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 5), 1)) {
- std::cout << "Test other two rectangles, second output wrong: Interval(" <<
- container[1].first << "), " << container[1].second << std::endl;
- }
- if(container[2] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(10, 15), -1)) {
- std::cout << "Test other two rectangles, third output wrong: Interval(" <<
- container[2].first << "), " << container[2].second << std::endl;
- }
- if(container[3] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), -1)) {
- std::cout << "Test other two rectangles, fourth output wrong: Interval(" <<
- container[3].first << "), " << container[3].second << std::endl;
- }
-
- //test two nonoverlapping rectangles
- container.clear();
- booleanOr = BooleanOp<int, Unit>();
- booleanOr.processInterval(container, interval_data<Unit>(0, 10), 1);
- booleanOr.advanceScan();
- booleanOr.processInterval(container, interval_data<Unit>(15, 25), 1);
- booleanOr.advanceScan();
- booleanOr.processInterval(container, interval_data<Unit>(0, 10), -1);
- booleanOr.advanceScan();
- booleanOr.processInterval(container, interval_data<Unit>(15, 25), -1);
- if(container.size() != 4) {
- std::cout << "Test two nonoverlapping rectangles, wrong output size\n";
- return false;
- }
- if(container[0] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), 1)) {
- std::cout << "Test two nonoverlapping rectangles, first output wrong: Interval(" <<
- container[0].first << "), " << container[0].second << std::endl;
- }
- if(container[1] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(15, 25), 1)) {
- std::cout << "Test two nonoverlapping rectangles, second output wrong: Interval(" <<
- container[1].first << "), " << container[1].second << std::endl;
- }
- if(container[2] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), -1)) {
- std::cout << "Test two nonoverlapping rectangles, third output wrong: Interval(" <<
- container[2].first << "), " << container[2].second << std::endl;
- }
- if(container[3] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(15, 25), -1)) {
- std::cout << "Test two nonoverlapping rectangles, fourth output wrong: Interval(" <<
- container[3].first << "), " << container[3].second << std::endl;
+ namespace boolean_op {
+ //self contained unit test for BooleanOr algorithm
+ template <typename Unit>
+ inline bool testBooleanOr() {
+ BooleanOp<int, Unit> booleanOr;
+ //test one rectangle
+ std::vector<std::pair<interval_data<Unit>, int> > container;
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), -1);
+ if(container.size() != 2) {
+ std::cout << "Test one rectangle, wrong output size\n";
+ return false;
+ }
+ if(container[0] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), 1)) {
+ std::cout << "Test one rectangle, first output wrong: Interval(" <<
+ container[0].first << "), " << container[0].second << std::endl;
+ }
+ if(container[1] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), -1)) {
+ std::cout << "Test one rectangle, second output wrong: Interval(" <<
+ container[1].first << "), " << container[1].second << std::endl;
+ }
+
+ //test two rectangles
+ container.clear();
+ booleanOr = BooleanOp<int, Unit>();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(5, 15), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), -1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(5, 15), -1);
+ if(container.size() != 4) {
+ std::cout << "Test two rectangles, wrong output size\n";
+ for(std::size_t i = 0; i < container.size(); ++i){
+ std::cout << container[i].first << "), " << container[i].second << std::endl;
+ }
+ return false;
+ }
+ if(container[0] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), 1)) {
+ std::cout << "Test two rectangles, first output wrong: Interval(" <<
+ container[0].first << "), " << container[0].second << std::endl;
+ }
+ if(container[1] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(10, 15), 1)) {
+ std::cout << "Test two rectangles, second output wrong: Interval(" <<
+ container[1].first << "), " << container[1].second << std::endl;
+ }
+ if(container[2] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 5), -1)) {
+ std::cout << "Test two rectangles, third output wrong: Interval(" <<
+ container[2].first << "), " << container[2].second << std::endl;
+ }
+ if(container[3] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(5, 15), -1)) {
+ std::cout << "Test two rectangles, fourth output wrong: Interval(" <<
+ container[3].first << "), " << container[3].second << std::endl;
+ }
+
+ //test two rectangles
+ container.clear();
+ booleanOr = BooleanOp<int, Unit>();
+ booleanOr.processInterval(container, interval_data<Unit>(5, 15), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(5, 15), -1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), -1);
+ if(container.size() != 4) {
+ std::cout << "Test other two rectangles, wrong output size\n";
+ for(std::size_t i = 0; i < container.size(); ++i){
+ std::cout << container[i].first << "), " << container[i].second << std::endl;
+ }
+ return false;
+ }
+ if(container[0] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(5, 15), 1)) {
+ std::cout << "Test other two rectangles, first output wrong: Interval(" <<
+ container[0].first << "), " << container[0].second << std::endl;
+ }
+ if(container[1] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 5), 1)) {
+ std::cout << "Test other two rectangles, second output wrong: Interval(" <<
+ container[1].first << "), " << container[1].second << std::endl;
+ }
+ if(container[2] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(10, 15), -1)) {
+ std::cout << "Test other two rectangles, third output wrong: Interval(" <<
+ container[2].first << "), " << container[2].second << std::endl;
+ }
+ if(container[3] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), -1)) {
+ std::cout << "Test other two rectangles, fourth output wrong: Interval(" <<
+ container[3].first << "), " << container[3].second << std::endl;
+ }
+
+ //test two nonoverlapping rectangles
+ container.clear();
+ booleanOr = BooleanOp<int, Unit>();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(15, 25), 1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(0, 10), -1);
+ booleanOr.advanceScan();
+ booleanOr.processInterval(container, interval_data<Unit>(15, 25), -1);
+ if(container.size() != 4) {
+ std::cout << "Test two nonoverlapping rectangles, wrong output size\n";
+ return false;
+ }
+ if(container[0] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), 1)) {
+ std::cout << "Test two nonoverlapping rectangles, first output wrong: Interval(" <<
+ container[0].first << "), " << container[0].second << std::endl;
+ }
+ if(container[1] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(15, 25), 1)) {
+ std::cout << "Test two nonoverlapping rectangles, second output wrong: Interval(" <<
+ container[1].first << "), " << container[1].second << std::endl;
+ }
+ if(container[2] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(0, 10), -1)) {
+ std::cout << "Test two nonoverlapping rectangles, third output wrong: Interval(" <<
+ container[2].first << "), " << container[2].second << std::endl;
+ }
+ if(container[3] != std::pair<interval_data<Unit>, int>(interval_data<Unit>(15, 25), -1)) {
+ std::cout << "Test two nonoverlapping rectangles, fourth output wrong: Interval(" <<
+ container[3].first << "), " << container[3].second << std::endl;
+ }
+ return true;
     }
- return true;
   }
-}
 
   void test_assign() {
     using namespace gtl;
@@ -393,7 +395,7 @@
     points.push_back(point_data<int>(10,0));
     polygon_45_data<int> poly;
     poly.set(points.begin(), points.end());
- polygon_45_set_data<int> ps;
+ polygon_45_set_data<int> ps;
     ps.insert(poly);
     std::vector<polygon_45_data<int> > polys;
     ps.get_polygons(polys);

Modified: sandbox/gtl/boost/polygon/polygon_traits.hpp
==============================================================================
--- sandbox/gtl/boost/polygon/polygon_traits.hpp (original)
+++ sandbox/gtl/boost/polygon/polygon_traits.hpp 2010-02-20 19:15:39 EST (Sat, 20 Feb 2010)
@@ -35,17 +35,8 @@
     }
   };
 
- template <typename T, typename enable = gtl_yes>
- struct polygon_traits {};
-
   template <typename T>
- struct polygon_traits<T,
- typename gtl_or_4<
- typename gtl_same_type<typename geometry_concept<T>::type, polygon_concept>::type,
- typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_concept>::type,
- typename gtl_same_type<typename geometry_concept<T>::type, polygon_with_holes_concept>::type,
- typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_with_holes_concept>::type
- >::type> {
+ struct polygon_traits_general {
     typedef typename T::coordinate_type coordinate_type;
     typedef typename T::iterator_type iterator_type;
     typedef typename T::point_type point_type;
@@ -72,11 +63,7 @@
   };
 
   template <typename T>
- struct polygon_traits< T,
- typename gtl_or<
- typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
- typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type
- >::type > {
+ struct polygon_traits_90 {
     typedef typename polygon_90_traits<T>::coordinate_type coordinate_type;
     typedef iterator_compact_to_points<typename polygon_90_traits<T>::compact_iterator_type, point_data<coordinate_type> > iterator_type;
     typedef point_data<coordinate_type> point_type;
@@ -104,6 +91,61 @@
     }
   };
 
+#ifndef BOOST_VERY_LITTLE_SFINAE
+
+ template <typename T, typename enable = gtl_yes>
+ struct polygon_traits {};
+
+ template <typename T>
+ struct polygon_traits<T,
+ typename gtl_or_4<
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_concept>::type,
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_concept>::type,
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_with_holes_concept>::type,
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_with_holes_concept>::type
+ >::type> : public polygon_traits_general<T> {};
+
+ template <typename T>
+ struct polygon_traits< T,
+ typename gtl_or<
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type
+ >::type > : public polygon_traits_90<T> {};
+
+#else
+
+ template <typename T, typename T_IF, typename T_ELSE>
+ struct gtl_ifelse {};
+ template <typename T_IF, typename T_ELSE>
+ struct gtl_ifelse<gtl_no, T_IF, T_ELSE> {
+ typedef T_ELSE type;
+ };
+ template <typename T_IF, typename T_ELSE>
+ struct gtl_ifelse<gtl_yes, T_IF, T_ELSE> {
+ typedef T_IF type;
+ };
+
+ template <typename T, typename enable = gtl_yes>
+ struct polygon_traits {};
+
+ template <typename T>
+ struct polygon_traits<T, typename gtl_or<typename gtl_or_4<
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_concept>::type,
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_concept>::type,
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_with_holes_concept>::type,
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_with_holes_concept>::type
+ >::type, typename gtl_or<
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type
+ >::type>::type > : public gtl_ifelse<typename gtl_or<
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
+ typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type >::type,
+ polygon_traits_90<T>,
+ polygon_traits_general<T> >::type {
+ };
+
+#endif
+
   template <typename T, typename enable = void>
   struct polygon_with_holes_traits {
     typedef typename T::iterator_holes_type iterator_holes_type;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk