Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58551 - in sandbox/gtl/boost/polygon: . detail
From: lucanus.j.simonson_at_[hidden]
Date: 2009-12-28 15:19:51


Author: ljsimons
Date: 2009-12-28 15:19:50 EST (Mon, 28 Dec 2009)
New Revision: 58551
URL: http://svn.boost.org/trac/boost/changeset/58551

Log:
performance improvements to aribtrary angle algorithms
Text files modified:
   sandbox/gtl/boost/polygon/detail/polygon_arbitrary_formation.hpp | 171 ++++++++++++++++++++++++++++++++++-----
   sandbox/gtl/boost/polygon/detail/scan_arbitrary.hpp | 134 +++++++++++++++++++++++++-----
   sandbox/gtl/boost/polygon/gmp_override.hpp | 9 +
   sandbox/gtl/boost/polygon/isotropy.hpp | 7 +
   4 files changed, 273 insertions(+), 48 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 2009-12-28 15:19:50 EST (Mon, 28 Dec 2009)
@@ -66,6 +66,11 @@
       return cross_1 == cross_2 && (cross_1_sign == cross_2_sign || cross_1 == 0);
     }
 
+ template <typename T>
+ static inline bool equal_slope_hp(const T& dx1, const T& dy1, const T& dx2, const T& dy2) {
+ return dx1 * dy2 == dx2 * dy1;
+ }
+
     static inline bool equal_slope(const Unit& x, const Unit& y,
                                    const Point& pt1, const Point& pt2) {
       const Point* pts[2] = {&pt1, &pt2};
@@ -170,20 +175,52 @@
     }
 
     static inline typename high_precision_type<Unit>::type evalAtXforY(Unit xIn, Point pt, Point other_pt) {
+ typename high_precision_type<Unit>::type
+ evalAtXforYret, evalAtXforYxIn, evalAtXforYx1, evalAtXforYy1, evalAtXforYdx1, evalAtXforYdx,
+ evalAtXforYdy, evalAtXforYx2, evalAtXforYy2, evalAtXforY0;
       //y = (x - x1)dy/dx + y1
       //y = (xIn - pt.x)*(other_pt.y-pt.y)/(other_pt.x-pt.x) + pt.y
       //assert pt.x != other_pt.x
- Unit x1 = pt.get(HORIZONTAL);
- Unit y1 = pt.get(VERTICAL);
       typedef typename high_precision_type<Unit>::type high_precision;
- high_precision dx1 = (high_precision)xIn - (high_precision)pt.get(HORIZONTAL);
- if(dx1 == high_precision(0)) return (high_precision)(pt.get(VERTICAL));
- high_precision dx = (high_precision)(other_pt.get(HORIZONTAL)) - (high_precision)x1;
- high_precision dy = (high_precision)(other_pt.get(VERTICAL)) - (high_precision)y1;
- high_precision y = (((high_precision)dx1) * (high_precision)dy / (high_precision)dx + (high_precision)y1);
- return y;
+ evalAtXforYxIn = (high_precision)xIn;
+ evalAtXforYx1 = pt.get(HORIZONTAL);
+ evalAtXforYy1 = pt.get(VERTICAL);
+ evalAtXforYdx1 = evalAtXforYxIn - evalAtXforYx1;
+ evalAtXforY0 = high_precision(0);
+ if(evalAtXforYdx1 == evalAtXforY0) return evalAtXforYret = evalAtXforYy1;
+ evalAtXforYx2 = (high_precision)other_pt.get(HORIZONTAL);
+ evalAtXforYy2 = (high_precision)other_pt.get(VERTICAL);
+
+ evalAtXforYdx = evalAtXforYx2 - evalAtXforYx1;
+ evalAtXforYdy = evalAtXforYy2 - evalAtXforYy1;
+ evalAtXforYret = ((evalAtXforYdx1) * evalAtXforYdy / evalAtXforYdx + evalAtXforYy1);
+ return evalAtXforYret;
     }
   
+ struct evalAtXforYPack {
+ typename high_precision_type<Unit>::type
+ evalAtXforYret, evalAtXforYxIn, evalAtXforYx1, evalAtXforYy1, evalAtXforYdx1, evalAtXforYdx,
+ evalAtXforYdy, evalAtXforYx2, evalAtXforYy2, evalAtXforY0;
+ inline const typename high_precision_type<Unit>::type& evalAtXforY(Unit xIn, Point pt, Point other_pt) {
+ //y = (x - x1)dy/dx + y1
+ //y = (xIn - pt.x)*(other_pt.y-pt.y)/(other_pt.x-pt.x) + pt.y
+ //assert pt.x != other_pt.x
+ typedef typename high_precision_type<Unit>::type high_precision;
+ evalAtXforYxIn = (high_precision)xIn;
+ evalAtXforYx1 = pt.get(HORIZONTAL);
+ evalAtXforYy1 = pt.get(VERTICAL);
+ evalAtXforYdx1 = evalAtXforYxIn - evalAtXforYx1;
+ evalAtXforY0 = high_precision(0);
+ if(evalAtXforYdx1 == evalAtXforY0) return evalAtXforYret = evalAtXforYy1;
+ evalAtXforYx2 = (high_precision)other_pt.get(HORIZONTAL);
+ evalAtXforYy2 = (high_precision)other_pt.get(VERTICAL);
+
+ evalAtXforYdx = evalAtXforYx2 - evalAtXforYx1;
+ evalAtXforYdy = evalAtXforYy2 - evalAtXforYy1;
+ evalAtXforYret = ((evalAtXforYdx1) * evalAtXforYdy / evalAtXforYdx + evalAtXforYy1);
+ return evalAtXforYret;
+ }
+ };
 
     static inline bool is_vertical(const half_edge& he) {
       return he.first.get(HORIZONTAL) == he.second.get(HORIZONTAL);
@@ -202,17 +239,25 @@
     private:
       Unit *x_; //x value at which to apply comparison
       int *justBefore_;
+ evalAtXforYPack * pack_;
     public:
- inline less_half_edge() : x_(0), justBefore_(0) {}
- inline less_half_edge(Unit *x, int *justBefore) : x_(x), justBefore_(justBefore) {}
- inline less_half_edge(const less_half_edge& that) : x_(that.x_), justBefore_(that.justBefore_) {}
- inline less_half_edge& operator=(const less_half_edge& that) { x_ = that.x_; justBefore_ = that.justBefore_; return *this; }
+ inline less_half_edge() : x_(0), justBefore_(0), pack_(0) {}
+ inline less_half_edge(Unit *x, int *justBefore, evalAtXforYPack * packIn) : x_(x), justBefore_(justBefore), pack_(packIn) {}
+ inline less_half_edge(const less_half_edge& that) : x_(that.x_), justBefore_(that.justBefore_),
+ pack_(that.pack_){}
+ inline less_half_edge& operator=(const less_half_edge& that) {
+ x_ = that.x_;
+ justBefore_ = that.justBefore_;
+ pack_ = that.pack_;
+ return *this; }
       inline bool operator () (const half_edge& elm1, const half_edge& elm2) const {
- //Unit y1 = evalAtXforY(*x_ + !*justBefore_, elm1.first, elm1.second);
- //Unit y2 = evalAtXforY(*x_ + !*justBefore_, elm2.first, elm2.second);
+ if(std::max(elm1.first.y(), elm1.second.y()) < std::min(elm2.first.y(), elm2.second.y()))
+ return true;
+ if(std::min(elm1.first.y(), elm1.second.y()) > std::max(elm2.first.y(), elm2.second.y()))
+ return false;
         typedef typename high_precision_type<Unit>::type high_precision;
- high_precision y1 = evalAtXforY(*x_, elm1.first, elm1.second);
- high_precision y2 = evalAtXforY(*x_, elm2.first, elm2.second);
+ high_precision y1 = pack_->evalAtXforY(*x_, elm1.first, elm1.second);
+ high_precision y2 = pack_->evalAtXforY(*x_, elm2.first, elm2.second);
         if(y1 < y2) return true;
         if(y1 == y2) {
           //if justBefore is true we invert the result of the comparison of slopes
@@ -337,6 +382,83 @@
       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;
+ inline bool compute_intersection(Point& intersection, const half_edge& he1, const half_edge& he2) {
+ 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(is_vertical(he1)) {
+ if(is_vertical(he2)) return false;
+ y_high = evalAtXforY(he1.first.get(HORIZONTAL), he2.first, he2.second);
+ Unit y = convert_high_precision_type<Unit>(y_high);
+ if(y_high < (high_precision)y) --y;
+ if(contains(rect1.get(VERTICAL), y, true)) {
+ intersection = Point(he1.first.get(HORIZONTAL), y);
+ return true;
+ } else {
+ return false;
+ }
+ } else if(is_vertical(he2)) {
+ y_high = evalAtXforY(he2.first.get(HORIZONTAL), he1.first, he1.second);
+ Unit y = convert_high_precision_type<Unit>(y_high);
+ if(y_high < (high_precision)y) --y;
+ if(contains(rect2.get(VERTICAL), y, true)) {
+ intersection = Point(he2.first.get(HORIZONTAL), y);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ //the bounding boxes of the two line segments intersect, so we check closer to find the intersection point
+ dy2 = (high_precision)(he2.second.get(VERTICAL)) -
+ (high_precision)(he2.first.get(VERTICAL));
+ dy1 = (high_precision)(he1.second.get(VERTICAL)) -
+ (high_precision)(he1.first.get(VERTICAL));
+ dx2 = (high_precision)(he2.second.get(HORIZONTAL)) -
+ (high_precision)(he2.first.get(HORIZONTAL));
+ dx1 = (high_precision)(he1.second.get(HORIZONTAL)) -
+ (high_precision)(he1.first.get(HORIZONTAL));
+ if(equal_slope_hp(dx1, dy1, dx2, dy2)) return false;
+ //the line segments have different slopes
+ //we can assume that the line segments are not vertical because such an intersection is handled elsewhere
+ x11 = (high_precision)(he1.first.get(HORIZONTAL));
+ x21 = (high_precision)(he2.first.get(HORIZONTAL));
+ y11 = (high_precision)(he1.first.get(VERTICAL));
+ y21 = (high_precision)(he2.first.get(VERTICAL));
+ //Unit exp_x = ((at)x11 * (at)dy1 * (at)dx2 - (at)x21 * (at)dy2 * (at)dx1 + (at)y21 * (at)dx1 * (at)dx2 - (at)y11 * (at)dx1 * (at)dx2) / ((at)dy1 * (at)dx2 - (at)dy2 * (at)dx1);
+ //Unit exp_y = ((at)y11 * (at)dx1 * (at)dy2 - (at)y21 * (at)dx2 * (at)dy1 + (at)x21 * (at)dy1 * (at)dy2 - (at)x11 * (at)dy1 * (at)dy2) / ((at)dx1 * (at)dy2 - (at)dx2 * (at)dy1);
+ x_num = (x11 * dy1 * dx2 - x21 * dy2 * dx1 + y21 * dx1 * dx2 - y11 * dx1 * dx2);
+ x_den = (dy1 * dx2 - dy2 * dx1);
+ y_num = (y11 * dx1 * dy2 - y21 * dx2 * dy1 + x21 * dy1 * dy2 - x11 * dy1 * dy2);
+ y_den = (dx1 * dy2 - dx2 * dy1);
+ x = x_num / x_den;
+ y = y_num / y_den;
+ //std::cout << "cross1 " << dy1 << " " << dx2 << " " << dy1 * dx2 << std::endl;
+ //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << std::endl;
+ //Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2);
+ //Unit exp_y = compute_x_intercept<at>(y11, y21, x11, x21, dx1, dx2, dy1, dy2);
+ Unit x_unit = convert_high_precision_type<Unit>(x);
+ Unit y_unit = convert_high_precision_type<Unit>(y);
+ //truncate downward if it went up due to negative number
+ if(x < (high_precision)x_unit) --x_unit;
+ if(y < (high_precision)y_unit) --y_unit;
+ //if(x != exp_x || y != exp_y)
+ // std::cout << exp_x << " " << exp_y << " " << x << " " << y << std::endl;
+ //Unit y1 = evalAtXforY(exp_x, he1.first, he1.second);
+ //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;
+ intersection = result;
+ return true;
+ }
+ };
+
     static inline bool compute_intersection(Point& intersection, const half_edge& he1, const half_edge& he2) {
       typedef typename high_precision_type<Unit>::type high_precision;
       typedef rectangle_data<Unit> Rectangle;
@@ -347,7 +469,7 @@
       if(is_vertical(he1)) {
         if(is_vertical(he2)) return false;
         high_precision y_high = evalAtXforY(he1.first.get(HORIZONTAL), he2.first, he2.second);
- Unit y = (Unit)y_high;
+ Unit y = convert_high_precision_type<Unit>(y_high);
         if(y_high < (high_precision)y) --y;
         if(contains(rect1.get(VERTICAL), y, true)) {
           intersection = Point(he1.first.get(HORIZONTAL), y);
@@ -357,7 +479,7 @@
         }
       } else if(is_vertical(he2)) {
         high_precision y_high = evalAtXforY(he2.first.get(HORIZONTAL), he1.first, he1.second);
- Unit y = (Unit)y_high;
+ Unit y = convert_high_precision_type<Unit>(y_high);
         if(y_high < (high_precision)y) --y;
         if(contains(rect2.get(VERTICAL), y, true)) {
           intersection = Point(he2.first.get(HORIZONTAL), y);
@@ -375,7 +497,7 @@
         (high_precision)(he2.first.get(HORIZONTAL));
       high_precision dx1 = (high_precision)(he1.second.get(HORIZONTAL)) -
         (high_precision)(he1.first.get(HORIZONTAL));
- if(equal_slope(dx1, dy1, dx2, dy2)) return false;
+ if(equal_slope_hp(dx1, dy1, dx2, dy2)) return false;
       //the line segments have different slopes
       //we can assume that the line segments are not vertical because such an intersection is handled elsewhere
       high_precision x11 = (high_precision)(he1.first.get(HORIZONTAL));
@@ -394,8 +516,8 @@
       //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << std::endl;
       //Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2);
       //Unit exp_y = compute_x_intercept<at>(y11, y21, x11, x21, dx1, dx2, dy1, dy2);
- Unit x_unit = (Unit)x;
- Unit y_unit = (Unit)y;
+ Unit x_unit = convert_high_precision_type<Unit>(x);
+ Unit y_unit = convert_high_precision_type<Unit>(y);
       //truncate downward if it went up due to negative number
       if(x < (high_precision)x_unit) --x_unit;
       if(y < (high_precision)y_unit) --y_unit;
@@ -1452,7 +1574,7 @@
               //we need to handle the hole now and not at the next input vertex
               active_tail_arbitrary* at = iter->second;
               high_precision precise_y = iter->first.evalAtX(x_);
- Unit fracture_y = (Unit)(precise_y);
+ Unit fracture_y = convert_high_precision_type<Unit>(precise_y);
               if(precise_y < fracture_y) --fracture_y;
               Point point(x_, fracture_y);
               verticalTail->getOtherActiveTail()->pushPoint(point);
@@ -1993,7 +2115,7 @@
                                  iterator previter) {
       active_tail_arbitrary* iterTail = (*previter).second;
       Point prevPoint(polygon_arbitrary_formation<Unit>::x_,
- (Unit)previter->first.evalAtX(polygon_arbitrary_formation<Unit>::x_));
+ convert_high_precision_type<Unit>(previter->first.evalAtX(polygon_arbitrary_formation<Unit>::x_)));
       iterTail->pushPoint(prevPoint);
       std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair =
         active_tail_arbitrary::createActiveTailsAsPair(prevPoint, true, 0, false);
@@ -2421,7 +2543,8 @@
             currentIter->pt.y() > (*iter).first.evalAtX(polygon_arbitrary_formation<Unit>::x_))) {
           //splice vertical pair into edge above
           active_tail_arbitrary* tailabove = (*iter).second;
- Point point(polygon_arbitrary_formation<Unit>::x_, (Unit)(*iter).first.evalAtX(polygon_arbitrary_formation<Unit>::x_));
+ Point point(polygon_arbitrary_formation<Unit>::x_,
+ convert_high_precision_type<Unit>((*iter).first.evalAtX(polygon_arbitrary_formation<Unit>::x_)));
           verticalPair.second->pushPoint(point);
           active_tail_arbitrary::joinChains(point, tailabove, verticalPair.first, true, output);
           (*iter).second = verticalPair.second;

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 2009-12-28 15:19:50 EST (Mon, 28 Dec 2009)
@@ -7,7 +7,9 @@
 */
 #ifndef BOOST_POLYGON_SCAN_ARBITRARY_HPP
 #define BOOST_POLYGON_SCAN_ARBITRARY_HPP
+#ifdef BOOST_POLYGON_DEBUG_FILE
 #include <fstream>
+#endif
 namespace boost { namespace polygon{
 
   template <typename Unit>
@@ -63,11 +65,85 @@
         return lp(pt, pt2) && lp(pt1, pt);
       return lp(pt, pt1) && lp(pt2, pt);
     }
-
+
+ template <typename iT>
+ static inline void compute_histogram_in_y(iT begin, iT end, int size, std::vector<std::pair<Unit, std::size_t> >& histogram) {
+ std::vector<std::pair<Unit, int> > ends;
+ ends.reserve(size * 2);
+ for(iT itr = begin ; itr != end; ++itr) {
+ int count = (*itr).first.first.y() < (*itr).first.second.y() ? 1 : -1;
+ ends.push_back(std::make_pair((*itr).first.first.y(), count));
+ ends.push_back(std::make_pair((*itr).first.second.y(), -count));
+ }
+ std::sort(ends.begin(), ends.end());
+ histogram.reserve(ends.size());
+ histogram.push_back(std::make_pair(ends.front().first, 0));
+ for(typename std::vector<std::pair<Unit, int> >::iterator itr = ends.begin(); itr != ends.end(); ++itr) {
+ if((*itr).first != histogram.back().first) {
+ histogram.push_back(std::make_pair((*itr).first, histogram.back().second));
+ }
+ histogram.back().second += (*itr).second;
+ }
+ }
+
+ template <typename iT>
+ static inline void compute_y_cuts(std::vector<Unit>& y_cuts, iT begin, iT end, std::size_t size) {
+ if(begin == end) return;
+ if(size < 10) return;
+ std::size_t min_cut = size;
+ iT cut = begin;
+ std::size_t position = 0;
+ std::size_t cut_size = 0;
+ for(iT itr = begin; itr != end; ++itr, ++position) {
+ if(position < size / 3)
+ continue;
+ if(size - position < size / 3) break;
+ if((*itr).second < min_cut) {
+ cut = itr;
+ min_cut = (*cut).second;
+ cut_size = position;
+ }
+ }
+ if(cut_size == 0 || (*cut).second > size / 3)
+ return;
+ compute_y_cuts(y_cuts, begin, cut, cut_size);
+ y_cuts.push_back((*cut).first);
+ compute_y_cuts(y_cuts, cut, end, size - cut_size);
+ }
+
+ template <typename iT>
+ static inline void validate_scan_divide_and_conquer(std::vector<std::set<Point> >& intersection_points,
+ iT begin, iT end) {
+ std::vector<std::pair<Unit, std::size_t> > histogram;
+ compute_histogram_in_y(begin, end, std::distance(begin, end), histogram);
+ std::vector<Unit> y_cuts;
+ compute_y_cuts(y_cuts, histogram.begin(), histogram.end(), histogram.size());
+ std::map<Unit, std::vector<std::pair<half_edge, segment_id> > > bins;
+ bins[histogram.front().first] = std::vector<std::pair<half_edge, segment_id> >();
+ for(typename std::vector<Unit>::iterator itr = y_cuts.begin(); itr != y_cuts.end(); ++itr) {
+ bins[*itr] = std::vector<std::pair<half_edge, segment_id> >();
+ }
+ for(iT itr = begin; itr != end; ++itr) {
+ typename std::map<Unit, std::vector<std::pair<half_edge, segment_id> > >::iterator lb =
+ bins.lower_bound(std::min((*itr).first.first.y(), (*itr).first.second.y()));
+ if(lb != bins.begin())
+ --lb;
+ typename std::map<Unit, std::vector<std::pair<half_edge, segment_id> > >::iterator ub =
+ bins.upper_bound(std::max((*itr).first.first.y(), (*itr).first.second.y()));
+ for( ; lb != ub; ++lb) {
+ (*lb).second.push_back(*itr);
+ }
+ }
+ validate_scan(intersection_points, bins[histogram.front().first].begin(), bins[histogram.front().first].end());
+ for(typename std::vector<Unit>::iterator itr = y_cuts.begin(); itr != y_cuts.end(); ++itr) {
+ validate_scan(intersection_points, bins[*itr].begin(), bins[*itr].end());
+ }
+ }
+
     //quadratic algorithm to do same work as optimal scan for cross checking
     //assume sorted input
     template <typename iT>
- static inline void validate_scan(std::map<segment_id, std::set<Point> >& intersection_points,
+ static inline void validate_scan(std::vector<std::set<Point> >& intersection_points,
                                      iT begin, iT end) {
       std::set<Point> pts;
       std::vector<std::pair<half_edge, segment_id> > data(begin, end);
@@ -76,6 +152,7 @@
           std::swap(data[i].first.first, data[i].first.second);
         }
       }
+ typename scanline_base<Unit>::compute_intersection_pack pack_;
       std::sort(data.begin(), data.end());
       //find all intersection points
       for(typename std::vector<std::pair<half_edge, segment_id> >::iterator outer = data.begin();
@@ -94,7 +171,7 @@
                         he1.first.get(HORIZONTAL)))
             break;
           Point intersection;
- if(compute_intersection(intersection, he1, he2)) {
+ if(pack_.compute_intersection(intersection, he1, he2)) {
             //their intersection point
             pts.insert(intersection);
           }
@@ -155,8 +232,9 @@
     template <typename iT>
     static inline void validate_scan(std::vector<std::pair<half_edge, int> >& output_segments,
                                      iT begin, iT end) {
- std::map<segment_id, std::set<Point> > intersection_points;
- validate_scan(intersection_points, begin, end);
+ std::vector<std::set<Point> > intersection_points(std::distance(begin, end));
+ validate_scan_divide_and_conquer(intersection_points, begin, end);
+ //validate_scan(intersection_points, begin, end);
       segment_intersections(output_segments, intersection_points, begin, end);
     }
 
@@ -223,7 +301,7 @@
 
     template <typename iT>
     static inline void segment_intersections(std::vector<std::pair<half_edge, int> >& output_segments,
- std::map<segment_id, std::set<Point> >& intersection_points,
+ std::vector<std::set<Point> >& intersection_points,
                                              iT begin, iT end) {
       for(iT iter = begin; iter != end; ++iter) {
         //less_point lp;
@@ -527,14 +605,14 @@
         return false;
       }
       input.pop_back();
- input.push_back(std::make_pair(half_edge(Point(1, 0), Point(11, 11)), 3));
+ input.push_back(std::make_pair(half_edge(Point(1, 0), Point(11, 11)), input.size()));
       edges.clear();
       validate_scan(edges, input.begin(), input.end());
       if(!verify_scan(result, edges.begin(), edges.end())) {
         stdcout << "s fail3 " << result.first << " " << result.second << "\n";
         return false;
       }
- input.push_back(std::make_pair(half_edge(Point(1, 0), Point(10, 11)), 4));
+ input.push_back(std::make_pair(half_edge(Point(1, 0), Point(10, 11)), input.size()));
       edges.clear();
       validate_scan(edges, input.begin(), input.end());
       if(!verify_scan(result, edges.begin(), edges.end())) {
@@ -542,14 +620,14 @@
         return false;
       }
       input.pop_back();
- input.push_back(std::make_pair(half_edge(Point(1, 2), Point(11, 11)), 5));
+ input.push_back(std::make_pair(half_edge(Point(1, 2), Point(11, 11)), input.size()));
       edges.clear();
       validate_scan(edges, input.begin(), input.end());
       if(!verify_scan(result, edges.begin(), edges.end())) {
         stdcout << "s fail5 " << result.first << " " << result.second << "\n";
         return false;
       }
- input.push_back(std::make_pair(half_edge(Point(0, 5), Point(0, 11)), 6));
+ input.push_back(std::make_pair(half_edge(Point(0, 5), Point(0, 11)), input.size()));
       edges.clear();
       validate_scan(edges, input.begin(), input.end());
       if(!verify_scan(result, edges.begin(), edges.end())) {
@@ -776,23 +854,23 @@
         return false;
       }
       edges.pop_back();
- edges.push_back(std::make_pair(half_edge(Point(1, 0), Point(11, 11)), 3));
+ edges.push_back(std::make_pair(half_edge(Point(1, 0), Point(11, 11)), edges.size()));
       if(!verify_scan(result, edges.begin(), edges.end())) {
         stdcout << "fail3\n";
         return false;
       }
- edges.push_back(std::make_pair(half_edge(Point(1, 0), Point(10, 11)), 4));
+ edges.push_back(std::make_pair(half_edge(Point(1, 0), Point(10, 11)), edges.size()));
       if(verify_scan(result, edges.begin(), edges.end())) {
         stdcout << "fail4\n";
         return false;
       }
       edges.pop_back();
- edges.push_back(std::make_pair(half_edge(Point(1, 2), Point(11, 11)), 5));
+ edges.push_back(std::make_pair(half_edge(Point(1, 2), Point(11, 11)), edges.size()));
       if(!verify_scan(result, edges.begin(), edges.end())) {
         stdcout << "fail5 " << result.first << " " << result.second << "\n";
         return false;
       }
- edges.push_back(std::make_pair(half_edge(Point(0, 5), Point(0, 11)), 6));
+ edges.push_back(std::make_pair(half_edge(Point(0, 5), Point(0, 11)), edges.size()));
       if(verify_scan(result, edges.begin(), edges.end())) {
         stdcout << "fail6 " << result.first << " " << result.second << "\n";
         return false;
@@ -866,10 +944,11 @@
     Unit x_;
     Unit y_;
     int just_before_;
+ 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) {
- less_half_edge lessElm(&x_, &just_before_);
+ 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_(),
@@ -921,11 +1000,11 @@
 #pragma warning( disable: 4127 )
 #endif
       while(true) {
- if(begin == end || (!first_iteration && (high_precision)(((*begin).first.first.get(VERTICAL)) != y ||
+ if(begin == end || (!first_iteration && ((high_precision)((*begin).first.first.get(VERTICAL)) != y ||
                                                                  (*begin).first.first.get(HORIZONTAL) != x_))) {
           //lookup iterator range in scanline for elements coming in from the left
           //that end at this y
- Point pt(x_, (Unit)y);
+ Point pt(x_, convert_high_precision_type<Unit>(y));
           //grab the properties coming in from below
           property_map properties_below;
           if(current_iter != scan_data_.end()) {
@@ -1384,25 +1463,28 @@
     typedef std::pair<half_edge, property_map> vertex_data;
 
     property_merge_data pmd;
+ typename scanline_base<Unit>::evalAtXforYPack evalAtXforYPack_;
 
     template<typename vertex_data_type>
     class less_vertex_data {
+ typename scanline_base<Unit>::evalAtXforYPack* pack_;
     public:
       less_vertex_data() {}
+ 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;
         if(lp(lvalue.first.first, rvalue.first.first)) return true;
         if(lp(rvalue.first.first, lvalue.first.first)) return false;
         Unit x = lvalue.first.first.get(HORIZONTAL);
         int just_before_ = 0;
- less_half_edge lhe(&x, &just_before_);
+ less_half_edge lhe(&x, &just_before_, pack_);
         return lhe(lvalue.first, rvalue.first);
       }
     };
 
 
     inline void sort_property_merge_data() {
- less_vertex_data<vertex_property> lvd;
+ less_vertex_data<vertex_property> lvd(&evalAtXforYPack_);
       std::sort(pmd.begin(), pmd.end(), lvd);
     }
   public:
@@ -2380,18 +2462,21 @@
     typedef std::pair<half_edge, property_map> vertex_data;
 
     property_merge_data pmd;
+ typename scanline_base<Unit>::evalAtXforYPack evalAtXforYPack_;
 
     template<typename vertex_data_type>
     class less_vertex_data {
+ typename scanline_base<Unit>::evalAtXforYPack* pack_;
     public:
       less_vertex_data() {}
+ 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;
         if(lp(lvalue.first.first, rvalue.first.first)) return true;
         if(lp(rvalue.first.first, lvalue.first.first)) return false;
         Unit x = lvalue.first.first.get(HORIZONTAL);
         int just_before_ = 0;
- less_half_edge lhe(&x, &just_before_);
+ less_half_edge lhe(&x, &just_before_, pack_);
         return lhe(lvalue.first, rvalue.first);
       }
     };
@@ -2450,7 +2535,7 @@
     };
 
     inline void sort_property_merge_data() {
- less_vertex_data<vertex_property> lvd;
+ less_vertex_data<vertex_property> lvd(&evalAtXforYPack_);
       std::sort(pmd.begin(), pmd.end(), lvd);
     }
   public:
@@ -2593,18 +2678,21 @@
     typedef std::pair<half_edge, property_map> vertex_data;
 
     property_merge_data pmd;
+ typename scanline_base<Unit>::evalAtXforYPack evalAtXforYPack_;
 
     template<typename vertex_data_type>
     class less_vertex_data {
+ typename scanline_base<Unit>::evalAtXforYPack* pack_;
     public:
       less_vertex_data() {}
+ 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;
         if(lp(lvalue.first.first, rvalue.first.first)) return true;
         if(lp(rvalue.first.first, lvalue.first.first)) return false;
         Unit x = lvalue.first.first.get(HORIZONTAL);
         int just_before_ = 0;
- less_half_edge lhe(&x, &just_before_);
+ less_half_edge lhe(&x, &just_before_, pack_);
         return lhe(lvalue.first, rvalue.first);
       }
     };
@@ -2669,7 +2757,7 @@
     };
 
     inline void sort_property_merge_data() {
- less_vertex_data<vertex_property> lvd;
+ less_vertex_data<vertex_property> lvd(&evalAtXforYPack_);
       std::sort(pmd.begin(), pmd.end(), lvd);
     }
   public:

Modified: sandbox/gtl/boost/polygon/gmp_override.hpp
==============================================================================
--- sandbox/gtl/boost/polygon/gmp_override.hpp (original)
+++ sandbox/gtl/boost/polygon/gmp_override.hpp 2009-12-28 15:19:50 EST (Mon, 28 Dec 2009)
@@ -111,9 +111,16 @@
   
   template <>
   struct high_precision_type<int> {
- typedef gmp_int type;
+ typedef mpq_class type;
   };
 
+ template <>
+ int convert_high_precision_type<int>(const mpq_class& v) {
+ mpz_class num = v.get_num();
+ mpz_class den = v.get_den();
+ num /= den;
+ return num.get_si();
+ };
 
 }
 }

Modified: sandbox/gtl/boost/polygon/isotropy.hpp
==============================================================================
--- sandbox/gtl/boost/polygon/isotropy.hpp (original)
+++ sandbox/gtl/boost/polygon/isotropy.hpp 2009-12-28 15:19:50 EST (Mon, 28 Dec 2009)
@@ -40,6 +40,8 @@
 typedef long long polygon_long_long_type;
 typedef unsigned long long polygon_ulong_long_type;
 #endif
+#include <boost/mpl/size_t.hpp>
+#include <boost/mpl/protect.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/mpl/and.hpp>
@@ -143,6 +145,11 @@
     typedef long double type;
   };
 
+ template <typename T>
+ T convert_high_precision_type(const typename high_precision_type<T>::type& v) {
+ return T(v);
+ };
+
   template <>
   struct coordinate_traits<int> {
     typedef int coordinate_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