Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80597 - trunk/boost/polygon/detail
From: lucanus.j.simonson_at_[hidden]
Date: 2012-09-19 14:08:45


Author: ljsimons
Date: 2012-09-19 14:08:44 EDT (Wed, 19 Sep 2012)
New Revision: 80597
URL: http://svn.boost.org/trac/boost/changeset/80597

Log:
using Andrii's event point construction and added support for multiple split edge handling
Text files modified:
   trunk/boost/polygon/detail/skeleton_detail.hpp | 563 +++++++++++++++++++++------------------
   1 files changed, 305 insertions(+), 258 deletions(-)

Modified: trunk/boost/polygon/detail/skeleton_detail.hpp
==============================================================================
--- trunk/boost/polygon/detail/skeleton_detail.hpp (original)
+++ trunk/boost/polygon/detail/skeleton_detail.hpp 2012-09-19 14:08:44 EDT (Wed, 19 Sep 2012)
@@ -108,10 +108,26 @@
         UnitOut x_out = gint.x() + ((p1.x() - gint.x())*dist2/dist1 + (p2.x()-gint.x()))/2;
         UnitOut y_out = gint.y() + ((p1.y() - gint.y())*dist2/dist1 + (p2.y()-gint.y()))/2;
         point_data<UnitOut> end_point(x_out, y_out);
+ if(orientation(segment2, end_point) < 0) {
+ x_out = gint.x() - ((p1.x() - gint.x())*dist2/dist1 + (p2.x()-gint.x()))/2;
+ y_out = gint.y() - ((p1.y() - gint.y())*dist2/dist1 + (p2.y()-gint.y()))/2;
+ end_point = point_data<UnitOut>(x_out, y_out);
+ }
+ std::cout << x_out << " " << y_out << "\n";
         if(orientation(segment2, end_point) != orientation(segment3, end_point)) {
           std::cout << "we want the other bisector in this case\n";
           y_out = gint.y() + ((p1.x() - gint.x())*dist2/dist1 + (p2.x()-gint.x()))/2;
           x_out = gint.x() - ((p1.y() - gint.y())*dist2/dist1 + (p2.y()-gint.y()))/2;
+ end_point = point_data<UnitOut>(x_out, y_out);
+ std::cout << x_out << " " << y_out << "\n";
+ std::cout << segment2.low().x() << " " << segment2.low().y() << " " <<
+ segment2.high().x() << " " << segment2.high().y() << " " << std::endl;
+ if(orientation(segment2, end_point) < 0) {
+ y_out = gint.y() - ((p1.x() - gint.x())*dist2/dist1 + (p2.x()-gint.x()))/2;
+ x_out = gint.x() + ((p1.y() - gint.y())*dist2/dist1 + (p2.y()-gint.y()))/2;
+ end_point = point_data<UnitOut>(x_out, y_out);
+ std::cout << x_out << " " << y_out << "\n";
+ }
         }
         end_point = point_data<UnitOut>(x_out, y_out);
         segment1.high(end_point);
@@ -172,13 +188,15 @@
         edge_type edge; //the edge that is next between this future intersection and the one stored in *next
         future_intersection* prev;
         future_intersection* next;
+ future_intersection* next_split_edge;
         skeleton_node* parent_node;
         output_coordinate_type active_distance;
         //split events that refer to the edge between this and next
         std::vector<typename std::set<event>::iterator> active_splits_on_next;
         std::string label;
         bool is_dead;
- future_intersection() : prev(0x0), next(0x0), parent_node(0x0), is_dead(false), active_distance(-1.0) {
+ future_intersection() : prev(0x0), next(0x0), next_split_edge(0x0),
+ parent_node(0x0), is_dead(false), active_distance(-1.0) {
           static char local_label = 'a';
           label = local_label;
           if(local_label == 'z')
@@ -287,7 +305,7 @@
         do {
           debug1("loop");
           if(orientation(current->prev->edge, current->edge) < 1) {
- std::cout << "initialize reflex vertex\n";
+ //std::cout << "initialize reflex vertex\n";
             future_intersection* inner = current->next->next;
             while(inner != current) {
               event e2;
@@ -385,8 +403,7 @@
         std::cout << s.low().x() << "," << s.low().y() << "->" << s.high().x() << "," << s.high().y() << "\n";
       }
 
- static bool compute_split_event_point(point_data<output_coordinate_type>& point,
- edge_type e1, edge_type e2, edge_type e3, edge_type e4, edge_type e5) {
+ static bool compute_split_event_point(event& e, edge_type e1, edge_type e2, edge_type e3, edge_type e4, edge_type e5) {
         debug1("compute_split_event_point");
         segment_type segment1, segment2, segment3, segment4, segment5;
         print_segment(e1);
@@ -403,51 +420,45 @@
           return false;
         }
         //compute the bisector of e1 and e2, this is the reflex vertex bisector
- if(bisector(segment1, e1, e2)) {
- debug1("has bisector1");
- if(bisector(segment2, e3, e4)) {
- debug1("has bisector2");
- if(bisector(segment3, e4, e5)) {
- debug1("has bisector3");
- //compute the edge event point using e1, e2, e2, e4 or e1, e2, e1, e4 if e4 is parallel to e2
- if(bisector(segment4, e1, e4)) {
- if(!generalized_intersection(point, segment1, segment4)) {
- debug1("no intersection 2");
- return false;
- }
- } else if(bisector(segment5, e2, e4)) {
- if(!generalized_intersection(point, segment1, segment5)) {
- debug1("no intersection 2");
- return false;
- }
- } else {
- debug1("no bisector4");
- return false;
- }
- std::cout << point.x() << " " << point.y() << std::endl;
- //test that point is on the coorect side of e1 and e2 and e4
- if(orientation(e1, point) <= 0)
- return false;
- if(orientation(e2, point) <= 0)
- return false;
- if(orientation(e4, point) <= 0)
- return false;
- debug1("passed simple orientation tests");
+ if(bisector(segment2, e3, e4)) {
+ debug1("has bisector2");
+ if(bisector(segment3, e4, e5)) {
+ debug1("has bisector3");
+ segment_data<coordinate_type> s1, s2, s3;
+ assign(s1, e1);
+ assign(s2, e2);
+ assign(s3, e4);
+ if(!create_event()(s1, s2, s3, &e)) {
+ return false;
+ }
+
+ point_data<output_coordinate_type> point = e.point;
+ std::cout << point.x() << " " << point.y() << std::endl;
+ //test that point is on the coorect side of e1 and e2 and e4
+ if(orientation(e1, point) <= 0)
+ return false;
+ if(orientation(e2, point) <= 0)
+ return false;
+ if(orientation(e4, point) <= 0)
+ return false;
+ debug1("passed simple orientation tests");
               //test that the point is on the correct side of the besector of e3,e4 and e4,e5
               //it should be clockwise the bisector of e3,e4 and counterclockwise the bisector of e4,e5
               //if e3,e4/e4e5 are concave then the correct sides will be reversed
- if(orientation(e3, e4) == orientation(segment2, point))
- return false;
- debug1("passed complex orientation test1");
- if(orientation(e4, e5) != orientation(segment3, point))
- return false;
- debug1("passed complex orientation test2");
- //we seem to have a good split event point
- return true;
- }
+ print_segment(e3);
+ print_segment(e4);
+ print_segment(segment2);
+ std::cout << orientation(e3, e4) << " " << orientation(segment2, point) << std::endl;
+ if(orientation(e3, e4) == orientation(segment2, point))
+ return false;
+ debug1("passed complex orientation test1");
+ if(orientation(e4, e5) != orientation(segment3, point))
+ return false;
+ debug1("passed complex orientation test2");
+ //we seem to have a good split event point
+ return true;
           }
         }
-
         return false;
       }
 
@@ -478,21 +489,6 @@
         point_data<output_coordinate_type> pt;
         if(compute_split_event_point(e, first->prev->edge, first->edge, opposite->prev->edge, opposite->edge, opposite->next->edge)) {
           std::cout << "found split event point\n";
- segment_type s1;
- assign(s1, opposite->edge);
- print_segment(opposite->edge);
- std::cout << pt.x() << " " << pt.y() << std::endl;
- output_coordinate_type dist = distance_squared_to_line(pt, s1);
- std::cout << "distance to split " << sqrt(dist) << std::endl;
- segment_data<coordinate_type> segment1, segment2, segment3;
- assign(segment1, first->prev->edge);
- assign(segment2, first->edge);
- assign(segment3, opposite->edge);
- event e2;
- create_event()(segment1, segment2, segment3, &e);
- std::cout << "Andrii's point " << e.x() << " " << e.y() << " " << e.r() << std::endl;
- e.point = pt;
- e.distance = dist;
           e.parent = first;
           e.split_on_next = opposite;
           return true;
@@ -500,23 +496,21 @@
         return false;
       }
 
- static bool compute_edge_event_point(point_data<output_coordinate_type>& point,
+ static bool compute_edge_event_point(event& e,
                                            edge_type e1, edge_type e2, edge_type e3, edge_type e4) {
- segment_type segment1, segment2;
- if(bisector(segment1, e1, e2)) {
- if(bisector(segment2, e3, e4)) {
- return (generalized_intersection(point, segment1, segment2));
- }
- }
- return false;
-
+ segment_data<coordinate_type> s1, s2, s3;
+ assign(s1, e1);
+ assign(s2, e2);
+ assign(s3, e4);
+ return create_event()(s1, s2, s3, &e);
       }
 
       static bool compute_edge_event(event& e, future_intersection* first, future_intersection* second,
                                      const rectangle_data<output_coordinate_type>& domain) {
         point_data<output_coordinate_type> pt;
- if(compute_edge_event_point(pt, first->prev->edge, first->edge, second->prev->edge, second->edge)) {
+ if(compute_edge_event_point(e, first->prev->edge, first->edge, second->prev->edge, second->edge)) {
           debug1("domain");
+ point_data<output_coordinate_type> pt = e.point;
           std::cout << pt.x() << " " << pt.y() << std::endl;
           //edge event points outside (or on the boundary of) the polygon bounding box are useless and not worth processing
           //they would never be reached by the forward progress of the algorithm through the event queue
@@ -525,19 +519,6 @@
             //compute distance from point to edge
             segment_type s1;
             assign(s1, first->edge);
- output_coordinate_type dist = distance_squared_to_line(pt, s1);
- output_coordinate_type dist2 = euclidean_distance(s1, pt);
- std::cout << "distance " << dist2 << std::endl;
- std::cout << "distance^2 " << dist << std::endl;
- segment_data<coordinate_type> segment1, segment2, segment3;
- assign(segment1, first->prev->edge);
- assign(segment2, first->edge);
- assign(segment3, second->edge);
- event e2;
- create_event()(segment1, segment2, segment3, &e);
- std::cout << "Andrii's point " << e.x() << " " << e.y() << " " << e.r() << std::endl;
- e.point = pt;
- e.distance = dist;
             e.parent = first;
             e.parent2 = second;
             e.split_on_next = 0x0;
@@ -607,6 +588,26 @@
           std::cout << current_event.parent->parent_node->label << "->" << skeleton.back()->label << std::endl;
           skeleton.back()->add_edge(current_event.parent->parent_node);
           current_event.parent->parent_node = skeleton.back();
+
+ //if the split_on_next edge was previously split it will have a circular linked list of potential
+ //future intersections that we need to search for the right one
+ if(current_event.split_on_next->next_split_edge) {
+ future_intersection* current = current_event.split_on_next;
+ do{
+ std::cout << current << std::endl;
+ if(!current->is_dead) {
+ debug1("is alive");
+ event e2;
+ if(compute_split_event(e2, current_event.parent, current)) {
+ debug1("found correct split edge");
+ current_event.split_on_next = current;
+ break;
+ }
+ }
+ current = current->next_split_edge;
+ } while (current != current_event.split_on_next);
+ }
+
           //event parent node is not dead
           //create one new future intersection associated with the with a copy of the "opposite" edge as its edge
           //that split edge will appear in both rings
@@ -617,6 +618,16 @@
           new_active->edge = current_event.split_on_next->edge;
           new_active->prev = current_event.parent->prev;
           new_active->next = current_event.split_on_next->next;
+
+ //link new future intersection into the circular list of future intersections
+ //associated with splits of this edge
+ new_active->next_split_edge = current_event.split_on_next->next_split_edge;
+ if(new_active->next_split_edge == 0x0)
+ new_active->next_split_edge = current_event.split_on_next;
+ std::cout << "next split edge " << new_active->next_split_edge << std::endl;
+ current_event.split_on_next->next_split_edge = new_active;
+ std::cout << "next split edge " << new_active << std::endl;
+
           new_active->parent_node = skeleton.back();
           new_active->active_distance = -1;
           new_active->next->prev = new_active;
@@ -658,7 +669,7 @@
             current_event.parent->next->parent_node->add_edge(current_event.parent->prev->parent_node);
             std::cout << current_event.parent->next->parent_node->label << "->" << current_event.parent->prev->parent_node->label << std::endl;
             current_event.parent->prev->is_dead = true;
- current_event.parent->prev->parent_node->linked_nodes[0] = current_event.parent->next->parent_node;
+ current_event.parent->prev->parent_node->add_edge(current_event.parent->next->parent_node);
             std::cout << current_event.parent->prev->parent_node->label << "->" << current_event.parent->next->parent_node->label << std::endl;
             current_event.parent->next->is_dead = true;
             return;
@@ -680,7 +691,7 @@
         while(!event_queue.empty()) {
           event current_event = event_queue.top();
           event_queue.pop();
- if(bound >=0 && current_event.distance > bound*bound)
+ if(bound >=0 && current_event.distance > bound)
             break;
           if(!current_event.parent->is_dead &&
              (current_event.parent2 == 0x0 || !current_event.parent2->is_dead))
@@ -715,180 +726,147 @@
         std::vector<skeleton_node*> skeleton;
         std::vector<future_intersection*> all_faces;
         event_queue_type event_queue;
- // initialize_skeleton(skeleton, all_faces, event_queue, rect);
- // if(skeleton.size() == 4 && all_faces.size() == 4) {
- // stdcout << event_queue.size() << stdendl;
- // for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
- // itr != skeleton.end(); ++itr) {
- // std::cout << (*itr) << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
- // ((*itr)->linked_nodes[0]) << " " <<
- // ((*itr)->linked_nodes[1]) << " " <<
- // ((*itr)->linked_nodes[2]) << "\n";
- // }
- // execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
- // for(typename std::vector<future_intersection*>::iterator itr = all_faces.begin();
- // itr != all_faces.end(); ++itr)
- // delete *itr;
- // all_faces.clear();
- // for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
- // itr != skeleton.end(); ++itr) {
- // std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
- // ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("0")) << " " <<
- // ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("0")) << " " <<
- // ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("0")) << "\n";
- // }
- // for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
- // itr != skeleton.end(); ++itr)
- // delete *itr;
- // skeleton.clear();
- // {
- // point_data<coordinate_type> pts[] = {point_data<coordinate_type>(120, 200),
- // point_data<coordinate_type>(300, 200),
- // point_data<coordinate_type>(300, 500),
- // point_data<coordinate_type>(100, 500),
- // point_data<coordinate_type>(100, 220),
- // };
- // polygon_data<coordinate_type> poly(pts, pts+5);
- // stdcout << "five point case\n";
- // initialize_skeleton(skeleton, all_faces, event_queue, poly);
- // execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
- // for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
- // itr != skeleton.end(); ++itr) {
- // std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
- // ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("0")) << " " <<
- // ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("0")) << " " <<
- // ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("0")) << "\n";
- // }
- // }
- // for(typename std::vector<future_intersection*>::iterator itr = all_faces.begin();
- // itr != all_faces.end(); ++itr)
- // delete *itr;
- // all_faces.clear();
- // for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
- // itr != skeleton.end(); ++itr)
- // delete *itr;
- // skeleton.clear();
-
- // {
- // point_data<coordinate_type> pts[] = {point_data<coordinate_type>(120, 200),
- // point_data<coordinate_type>(280, 200),
- // point_data<coordinate_type>(300, 220),
- // point_data<coordinate_type>(300, 480),
- // point_data<coordinate_type>(280, 500),
- // point_data<coordinate_type>(120, 500),
- // point_data<coordinate_type>(100, 480),
- // point_data<coordinate_type>(100, 220),
- // };
- // polygon_data<coordinate_type> poly(pts, pts+8);
- // stdcout << "eight point case\n";
- // initialize_skeleton(skeleton, all_faces, event_queue, poly);
- // execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
- // for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
- // itr != skeleton.end(); ++itr) {
- // std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
- // ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("0")) << " " <<
- // ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("0")) << " " <<
- // ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("0")) << "\n";
- // }
- // }
-
- // for(typename std::vector<future_intersection*>::iterator itr = all_faces.begin();
- // itr != all_faces.end(); ++itr)
- // delete *itr;
- // all_faces.clear();
- // for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
- // itr != skeleton.end(); ++itr)
- // delete *itr;
- // skeleton.clear();
- // {
- // point_data<coordinate_type> pts[] = {point_data<coordinate_type>(120, 200),
- // point_data<coordinate_type>(280, 200),
- // point_data<coordinate_type>(300, 220),
- // point_data<coordinate_type>(300, 480-100),
- // point_data<coordinate_type>(280, 500-100),
- // point_data<coordinate_type>(120, 500-100),
- // point_data<coordinate_type>(100, 480-100),
- // point_data<coordinate_type>(100, 220),
- // };
- // polygon_data<coordinate_type> poly(pts, pts+8);
- // stdcout << "co-circular eight point case\n";
- // initialize_skeleton(skeleton, all_faces, event_queue, poly);
- // execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
- // for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
- // itr != skeleton.end(); ++itr) {
- // std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
- // ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("0")) << " " <<
- // ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("0")) << " " <<
- // ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("0")) << "\n";
- // }
- // }
-
- // for(typename std::vector<future_intersection*>::iterator itr = all_faces.begin();
- // itr != all_faces.end(); ++itr)
- // delete *itr;
- // all_faces.clear();
- // for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
- // itr != skeleton.end(); ++itr)
- // delete *itr;
- // skeleton.clear();
-
-
-
- // {
- // point_data<coordinate_type> pts[] = {point_data<coordinate_type>(100, 200),
- // point_data<coordinate_type>(150, 220),
- // point_data<coordinate_type>(200, 200),
- // point_data<coordinate_type>(180, 250),
- // point_data<coordinate_type>(200, 300),
- // point_data<coordinate_type>(150, 280),
- // point_data<coordinate_type>(100, 300),
- // point_data<coordinate_type>(120, 250),
- // };
- // polygon_data<coordinate_type> poly(pts, pts+8);
- // stdcout << "ninja star\n";
- // initialize_skeleton(skeleton, all_faces, event_queue, poly);
- // execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
- // for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
- // itr != skeleton.end(); ++itr) {
- // std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
- // ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("0")) << " " <<
- // ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("0")) << " " <<
- // ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("0")) << "\n";
- // }
- // }
-
- // for(typename std::vector<future_intersection*>::iterator itr = all_faces.begin();
- // itr != all_faces.end(); ++itr)
- // delete *itr;
- // all_faces.clear();
- // for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
- // itr != skeleton.end(); ++itr)
- // delete *itr;
- // skeleton.clear();
-
- // {
- // point_data<coordinate_type> pts[] = {point_data<coordinate_type>(100, 200),
- // point_data<coordinate_type>(140, 240),
- // point_data<coordinate_type>(200, 200),
- // point_data<coordinate_type>(160, 240),
- // point_data<coordinate_type>(200, 300),
- // point_data<coordinate_type>(160, 260),
- // point_data<coordinate_type>(100, 300),
- // point_data<coordinate_type>(140, 260),
- // };
- // polygon_data<coordinate_type> poly(pts, pts+8);
- // stdcout << "evil ninja star\n";
- // initialize_skeleton(skeleton, all_faces, event_queue, poly);
- // std::cout << event_queue.size() << " GREP\n";
- // execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
- // for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
- // itr != skeleton.end(); ++itr) {
- // std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
- // ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("0")) << " " <<
- // ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("0")) << " " <<
- // ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("0")) << "\n";
- // }
- // }
+ initialize_skeleton(skeleton, all_faces, event_queue, rect);
+ if(skeleton.size() == 4 && all_faces.size() == 4) {
+ stdcout << event_queue.size() << stdendl;
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr) {
+ std::cout << (*itr) << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
+ ((*itr)->linked_nodes[0]) << " " <<
+ ((*itr)->linked_nodes[1]) << " " <<
+ ((*itr)->linked_nodes[2]) << "\n";
+ }
+ execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
+ for(typename std::vector<future_intersection*>::iterator itr = all_faces.begin();
+ itr != all_faces.end(); ++itr)
+ delete *itr;
+ all_faces.clear();
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr) {
+ std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
+ ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("0")) << " " <<
+ ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("0")) << " " <<
+ ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("0")) << "\n";
+ }
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr)
+ delete *itr;
+ skeleton.clear();
+ {
+ point_data<coordinate_type> pts[] = {point_data<coordinate_type>(120, 200),
+ point_data<coordinate_type>(300, 200),
+ point_data<coordinate_type>(300, 500),
+ point_data<coordinate_type>(100, 500),
+ point_data<coordinate_type>(100, 220),
+ };
+ polygon_data<coordinate_type> poly(pts, pts+5);
+ stdcout << "five point case\n";
+ initialize_skeleton(skeleton, all_faces, event_queue, poly);
+ execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr) {
+ std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
+ ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("0")) << " " <<
+ ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("0")) << " " <<
+ ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("0")) << "\n";
+ }
+ }
+ for(typename std::vector<future_intersection*>::iterator itr = all_faces.begin();
+ itr != all_faces.end(); ++itr)
+ delete *itr;
+ all_faces.clear();
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr)
+ delete *itr;
+ skeleton.clear();
+
+ {
+ point_data<coordinate_type> pts[] = {point_data<coordinate_type>(120, 200),
+ point_data<coordinate_type>(280, 200),
+ point_data<coordinate_type>(300, 220),
+ point_data<coordinate_type>(300, 480),
+ point_data<coordinate_type>(280, 500),
+ point_data<coordinate_type>(120, 500),
+ point_data<coordinate_type>(100, 480),
+ point_data<coordinate_type>(100, 220),
+ };
+ polygon_data<coordinate_type> poly(pts, pts+8);
+ stdcout << "eight point case\n";
+ initialize_skeleton(skeleton, all_faces, event_queue, poly);
+ execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr) {
+ std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
+ ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("0")) << " " <<
+ ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("0")) << " " <<
+ ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("0")) << "\n";
+ }
+ }
+
+ for(typename std::vector<future_intersection*>::iterator itr = all_faces.begin();
+ itr != all_faces.end(); ++itr)
+ delete *itr;
+ all_faces.clear();
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr)
+ delete *itr;
+ skeleton.clear();
+ {
+ point_data<coordinate_type> pts[] = {point_data<coordinate_type>(120, 200),
+ point_data<coordinate_type>(280, 200),
+ point_data<coordinate_type>(300, 220),
+ point_data<coordinate_type>(300, 480-100),
+ point_data<coordinate_type>(280, 500-100),
+ point_data<coordinate_type>(120, 500-100),
+ point_data<coordinate_type>(100, 480-100),
+ point_data<coordinate_type>(100, 220),
+ };
+ polygon_data<coordinate_type> poly(pts, pts+8);
+ stdcout << "co-circular eight point case\n";
+ initialize_skeleton(skeleton, all_faces, event_queue, poly);
+ execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr) {
+ std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
+ ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("0")) << " " <<
+ ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("0")) << " " <<
+ ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("0")) << "\n";
+ }
+ }
+
+ for(typename std::vector<future_intersection*>::iterator itr = all_faces.begin();
+ itr != all_faces.end(); ++itr)
+ delete *itr;
+ all_faces.clear();
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr)
+ delete *itr;
+ skeleton.clear();
+
+
+
+ {
+ point_data<coordinate_type> pts[] = {point_data<coordinate_type>(100, 200),
+ point_data<coordinate_type>(150, 220),
+ point_data<coordinate_type>(200, 200),
+ point_data<coordinate_type>(180, 250),
+ point_data<coordinate_type>(200, 300),
+ point_data<coordinate_type>(150, 280),
+ point_data<coordinate_type>(100, 300),
+ point_data<coordinate_type>(120, 250),
+ };
+ polygon_data<coordinate_type> poly(pts, pts+8);
+ stdcout << "ninja star\n";
+ initialize_skeleton(skeleton, all_faces, event_queue, poly);
+ execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr) {
+ std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
+ ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("0")) << " " <<
+ ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("0")) << " " <<
+ ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("0")) << "\n";
+ }
+ }
 
           for(typename std::vector<future_intersection*>::iterator itr = all_faces.begin();
               itr != all_faces.end(); ++itr)
@@ -900,6 +878,38 @@
           skeleton.clear();
 
           {
+ point_data<coordinate_type> pts[] = {point_data<coordinate_type>(100, 200),
+ point_data<coordinate_type>(140, 240),
+ point_data<coordinate_type>(200, 200),
+ point_data<coordinate_type>(160, 240),
+ point_data<coordinate_type>(200, 300),
+ point_data<coordinate_type>(160, 260),
+ point_data<coordinate_type>(100, 300),
+ point_data<coordinate_type>(140, 260),
+ };
+ polygon_data<coordinate_type> poly(pts, pts+8);
+ stdcout << "evil ninja star\n";
+ initialize_skeleton(skeleton, all_faces, event_queue, poly);
+ std::cout << event_queue.size() << " GREP\n";
+ execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr) {
+ std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
+ ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("0")) << " " <<
+ ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("0")) << " " <<
+ ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("0")) << "\n";
+ }
+ }
+
+ for(typename std::vector<future_intersection*>::iterator itr = all_faces.begin();
+ itr != all_faces.end(); ++itr)
+ delete *itr;
+ all_faces.clear();
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr)
+ delete *itr;
+ skeleton.clear();
+
           {
           point_data<coordinate_type> pts[] = {point_data<coordinate_type>(100, 200),
                                                point_data<coordinate_type>(300, 200),
@@ -929,6 +939,43 @@
             delete *itr;
           skeleton.clear();
 
+ {
+ point_data<coordinate_type> pts[] = {point_data<coordinate_type>(100, 200),
+ point_data<coordinate_type>(300, 200),
+ point_data<coordinate_type>(300, 500),
+ point_data<coordinate_type>(100, 500),
+ point_data<coordinate_type>(100, 490),
+ point_data<coordinate_type>(120, 490),
+ point_data<coordinate_type>(100, 489),
+ point_data<coordinate_type>(100, 450),
+ point_data<coordinate_type>(122, 450),
+ point_data<coordinate_type>(100, 449),
+ point_data<coordinate_type>(100, 420),
+ point_data<coordinate_type>(120, 420),
+ point_data<coordinate_type>(100, 419),
+ };
+ polygon_data<coordinate_type> poly(pts, pts+10);
+ stdcout << "multiple split\n";
+ initialize_skeleton(skeleton, all_faces, event_queue, poly);
+ execute_skeleton(skeleton, all_faces, event_queue, domain, 1000);
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr) {
+ std::cout << (*itr)->label << " " << (*itr)->vertex.x() << " " << (*itr)->vertex.y() << " " <<
+ ( ((*itr)->linked_nodes[0]) ? (*itr)->linked_nodes[0]->label : std::string("null")) << " " <<
+ ( ((*itr)->linked_nodes[1]) ? (*itr)->linked_nodes[1]->label : std::string("null")) << " " <<
+ ( ((*itr)->linked_nodes[2]) ? (*itr)->linked_nodes[2]->label : std::string("null")) << "\n";
+ }
+ }
+
+ for(typename std::vector<future_intersection*>::iterator itr = all_faces.begin();
+ itr != all_faces.end(); ++itr)
+ delete *itr;
+ all_faces.clear();
+ for(typename std::vector<skeleton_node*>::iterator itr = skeleton.begin();
+ itr != skeleton.end(); ++itr)
+ delete *itr;
+ skeleton.clear();
+
           return true;
         }
         return false;


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