diff --git a/poly2tri/common/shapes.cc b/poly2tri/common/shapes.cc index 7918ab3..01fecb9 100644 --- a/poly2tri/common/shapes.cc +++ b/poly2tri/common/shapes.cc @@ -36,11 +36,7 @@ Triangle::Triangle(Point& a, Point& b, Point& c) { neighbors_[0] = NULL; neighbors_[1] = NULL; neighbors_[2] = NULL; constrained_edge[0] = constrained_edge[1] = constrained_edge[2] = false; delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false; - interior = false; -} - -Triangle::~Triangle() { - printf("bye triangle\n"); + interior_ = false; } // Update neighbor pointers @@ -140,8 +136,7 @@ int Triangle::EdgeIndex(const Point* p1, const Point* p2) { } else if(points_[2] == p2){ return 1; } - } - else if(points_[1] == p1) { + } else if(points_[1] == p1) { if(points_[2] == p2) { return 0; } else if(points_[0] == p2) { @@ -162,16 +157,7 @@ void Triangle::MarkConstrainedEdge(const int index) { } void Triangle::MarkConstrainedEdge(Edge& edge) { - MarkConstrainedEdge(edge.p, edge.q); - if((edge.q == points_[0] && edge.p == points_[1]) || (edge.q == points_[1] && edge.p == points_[0])) { - constrained_edge[2] = true; - } else if((edge.q == points_[0] && edge.p == points_[2]) || (edge.q == points_[2] && edge.p == points_[0])) { - constrained_edge[1] = true; - } else if(( edge.q == points_[1] && edge.p == points_[2]) || (edge.q == points_[2] && edge.p == points_[1])) { - constrained_edge[0] = true; - } - } // Mark edge as constrained diff --git a/poly2tri/common/shapes.h b/poly2tri/common/shapes.h index cd8f07f..fb666e2 100644 --- a/poly2tri/common/shapes.h +++ b/poly2tri/common/shapes.h @@ -91,18 +91,6 @@ struct Point { y /= len; return len; } - - bool operator < (Point& b) { - if (y < b.y) { - return true; - } else if (y == b.y) { - // Make sure q is point with greater x value - if(x < b.x) { - return true; - } - } - return false; - } }; @@ -128,7 +116,7 @@ struct Edge { } q->edge_list.push_back(*this); - + //printf("%i\n", q->edge_list.size()); } }; @@ -142,15 +130,11 @@ public: /// Constructor Triangle(Point& a, Point& b, Point& c); - // Destroctor - ~Triangle(); /// Flags to determine if an edge is a Constrained edge bool constrained_edge[3]; /// Flags to determine if an edge is a Delauney edge bool delaunay_edge[3]; - /// Has this triangle been marked as an interior triangle? - bool interior; Point* GetPoint(const int& index); Point* PointCW(Point& point); @@ -187,6 +171,9 @@ public: void ClearNeighbors(); void ClearDelunayEdges(); + inline bool IsInterior(); + inline void IsInterior(bool b); + Triangle& NeighborAcross(Point& opoint); void DebugPrint(); @@ -197,15 +184,18 @@ private: Point* points_[3]; /// Neighbor list Triangle* neighbors_[3]; + + /// Has this triangle been marked as an interior triangle? + bool interior_; }; -inline bool operator < (const Point& a, const Point& b) { - if (a.y < b.y) { +inline bool cmp (const Point* a, const Point* b) { + if (a->y < b->y) { return true; - } else if (a.y == b.y) { + } else if (a->y == b->y) { // Make sure q is point with greater x value - if(a.x < b.x) { + if(a->x < b->x) { return true; } } @@ -235,10 +225,6 @@ inline bool operator != (const Point& a, const Point& b) { return a.x != b.x && a.y != b.y; } -inline bool operator != (const Node& a, const Node& b) { - return a != b; -} - /// Peform the dot product on two vectors. inline double Dot(const Point& a, const Point& b) { return a.x * b.x + a.y * b.y; @@ -281,5 +267,13 @@ inline bool Triangle::Contains(Point* p, Point* q) { return Contains(p) && Contains(q); } +inline bool Triangle::IsInterior() { + return interior_; +} + +inline void Triangle::IsInterior(bool b) { + interior_ = b; +} + #endif diff --git a/poly2tri/sweep/cdt.cc b/poly2tri/sweep/cdt.cc index 6332414..5410c8b 100644 --- a/poly2tri/sweep/cdt.cc +++ b/poly2tri/sweep/cdt.cc @@ -43,7 +43,7 @@ void CDT::Triangulate() { sweep_->Triangulate(*sweep_context_); } -std::list CDT::GetTriangles() { +std::vector CDT::GetTriangles() { return sweep_context_->GetTriangles(); } diff --git a/poly2tri/sweep/cdt.h b/poly2tri/sweep/cdt.h index 67c6a06..de49110 100644 --- a/poly2tri/sweep/cdt.h +++ b/poly2tri/sweep/cdt.h @@ -45,7 +45,7 @@ public: /// Triangulate points void Triangulate(); /// Get Delaunay triangles - std::list GetTriangles(); + std::vector GetTriangles(); private: diff --git a/poly2tri/sweep/sweep.cc b/poly2tri/sweep/sweep.cc index b195ac4..b117e04 100644 --- a/poly2tri/sweep/sweep.cc +++ b/poly2tri/sweep/sweep.cc @@ -35,31 +35,22 @@ // Triangulate simple polygon with holes void Sweep::Triangulate(SweepContext& tcx) { - + tcx.CreateAdvancingFront(); - // Sweep points; build mesh SweepPoints(tcx); - - /* - // Finalize triangulation - if( tcx.getTriangulationMode() == TriangulationMode.Polygon ) { - finalizationPolygon( tcx ); - } else { - finalizationConvexHull( tcx ); - } - */ + // Clean up + FinalizationPolygon(tcx); } -void Sweep::SweepPoints(SweepContext& tcx ) { +void Sweep::SweepPoints(SweepContext& tcx) { for(int i = 1; i < tcx.point_count(); i++ ) { Point& point = *tcx.GetPoint(i); - - Node& node = PointEvent(tcx, point); - + Node& node = PointEvent(tcx, point); + for(int i = 0; i < point.edge_list.size(); i++) { EdgeEvent(tcx, point.edge_list[i], node); } @@ -68,6 +59,19 @@ void Sweep::SweepPoints(SweepContext& tcx ) { } +void Sweep::FinalizationPolygon(SweepContext& tcx) { + + // Get an Internal triangle to start with + Triangle* t = tcx.front()->head()->next->triangle; + Point* p = tcx.front()->head()->next->point; + while(!t->GetConstrainedEdgeCW(*p)) { + t = t->NeighborCCW(*p); + } + + // Collect interior triangles constrained by edges + tcx.MeshClean(*t); +} + /** * Find closes node to the left of the new point and * create a new triangle. If needed new holes and basins @@ -102,7 +106,7 @@ void Sweep::EdgeEvent(SweepContext& tcx, Edge& edge, Node& node) { if(IsEdgeSideOfTriangle(*node.triangle, *edge.p, *edge.q)){ return; } - + // For now we will do all needed filling // TODO: integrate with flip process might give some better performance // but for now this avoid the issue with cases that needs both flips and fills @@ -615,7 +619,7 @@ void Sweep::TurnAdvancingFrontConvex(SweepContext& tcx, Node& b, Node& c) { Node& first = b; - while(c != *tcx.front()->tail()) { + while(&c != tcx.front()->tail()) { if(Orient2d(*b.point, *c.point, *c.next->point) == CCW) { // [b,c,d] Concave - fill around c @@ -623,7 +627,7 @@ void Sweep::TurnAdvancingFrontConvex(SweepContext& tcx, Node& b, Node& c) { c = *c.next; } else { // [b,c,d] Convex - if(b != first && Orient2d(*b.prev->point, *b.point, *c.point) == CCW) { + if(&b != &first && Orient2d(*b.prev->point, *b.point, *c.point) == CCW) { // [a,b,c] Concave - fill around b Fill(tcx, b); b = *b.prev; diff --git a/poly2tri/sweep/sweep.h b/poly2tri/sweep/sweep.h index b190900..53002f7 100644 --- a/poly2tri/sweep/sweep.h +++ b/poly2tri/sweep/sweep.h @@ -111,6 +111,8 @@ private: Point& NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op ); - void FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle, Triangle& t, Point& p); + void FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle, Triangle& t, Point& p); + + void FinalizationPolygon(SweepContext& tcx); }; diff --git a/poly2tri/sweep/sweep_context.cc b/poly2tri/sweep/sweep_context.cc index 2aec4d3..150d54e 100644 --- a/poly2tri/sweep/sweep_context.cc +++ b/poly2tri/sweep/sweep_context.cc @@ -9,27 +9,26 @@ SweepContext::SweepContext(Point** polyline, const int& point_count) { basin = Basin(); edge_event = EdgeEvent(); - for(int i = 0; i < point_count; i++) { - points_.push_back(**&polyline[i]); - } + points_ = polyline; + point_count_ = point_count; - InitEdges(polyline, point_count); + InitEdges(points_, point_count_); InitTriangulation(); } -std::list SweepContext::GetTriangles() { - return tri_list_; +std::vector SweepContext::GetTriangles() { + return triangles_; } void SweepContext::InitTriangulation() { - double xmax(points_[0].x), xmin(points_[0].x); - double ymax(points_[0].y), ymin(points_[0].y); + double xmax(points_[0]->x), xmin(points_[0]->x); + double ymax(points_[0]->y), ymin(points_[0]->y); // Calculate bounds. - for(int i = 0; i < points_.size(); i++) { - Point p = points_[i]; + for(int i = 0; i < point_count_; i++) { + Point p = *points_[i]; if(p.x > xmax) xmax = p.x; if(p.x < xmin) @@ -47,26 +46,46 @@ void SweepContext::InitTriangulation() { // Sort points along y-axis double init_time = glfwGetTime(); - std::sort(points_.begin(), points_.end()); + std::sort(points_, points_ + point_count_, cmp); double dt = glfwGetTime() - init_time; printf("Sort time (secs) = %f\n", dt); - + + /* + printf("*************************\n"); + for(int i = 0; i < point_count_; i++) { + printf("%p ", points_[i]); + printf("%f,%f\n", points_[i]->x, points_[i]->y); + } + + printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + for(int i = 0; i < edge_list.size(); i++) { + printf("%p, %p\n", edge_list[i]->p, edge_list[i]->q); + } + */ + } void SweepContext::InitEdges(Point** polyline, const int& point_count) { for(int i = 0; i < point_count; i++) { - int j = i < points_.size() - 1 ? i + 1 : 0; - edge_list.push_back(new Edge(**&polyline[i], **&polyline[j])); + int j = i < point_count - 1 ? i + 1 : 0; + edge_list.push_back(new Edge(*polyline[i], *polyline[j])); } + + /* + for(int i = 0; i < edge_list.size(); i++) { + printf("%p, %p\n", edge_list[i]->p, edge_list[i]->q); + } + */ + } Point* SweepContext::GetPoint(const int& index) { - return &points_[index]; + return points_[index]; } void SweepContext::AddToMap(Triangle* triangle ) { - tri_list_.push_back(triangle); + map_.push_back(triangle); } Node& SweepContext::LocateNode(Point& point) { @@ -77,9 +96,9 @@ Node& SweepContext::LocateNode(Point& point) { void SweepContext::CreateAdvancingFront() { // Initial triangle - Triangle* triangle = new Triangle(points_[0], *tail_, *head_); + Triangle* triangle = new Triangle(*points_[0], *tail_, *head_); - tri_list_.push_back(triangle); + map_.push_back(triangle); front_ = new AdvancingFront; @@ -114,46 +133,22 @@ void SweepContext::MapTriangleToNodes(Triangle& t) { } void SweepContext::RemoveFromMap(Triangle* triangle) { - tri_list_.remove(triangle); + map_.remove(triangle); } -/* -void SweepContext::MeshClean(Triangle& triangle) { - pointset_.ClearTriangulation(); - MeshCleanReq(triangle); -} +void SweepContext::MeshClean(Triangle& triangle ) { -AFront SweepContext::front_() { - return front_; -} - -void SweepContext::Clear() { - super.clear(); - tri_list_.Clear(); -} - - -Node* SweepContext::LocateNode(Point& point) { - // TODO implement tree - return front_.Locate(point.x); -} - -/* - -void SweepContext::MeshCleanReq(Triangle& triangle ) { - if(triangle != NULL && !triangle.isInterior()) { + if(&triangle != NULL && !triangle.IsInterior()) { triangle.IsInterior(true); - pointset_.AddTriangle(triangle); + triangles_.push_back(&triangle); for(int i = 0; i < 3; i++) { - if(!triangle.cEdge[i]) - MeshCleanReq(triangle.neighbors[i]); - } - } + if(!triangle.constrained_edge[i]) + MeshClean(*triangle.GetNeighbor(i)); + } + } } -*/ SweepContext::~SweepContext() { - //delete [] points_; delete head_; delete tail_; delete front_; diff --git a/poly2tri/sweep/sweep_context.h b/poly2tri/sweep/sweep_context.h index 65e05bb..253e4e1 100644 --- a/poly2tri/sweep/sweep_context.h +++ b/poly2tri/sweep/sweep_context.h @@ -80,7 +80,9 @@ public: AdvancingFront* front(); - std::list GetTriangles(); + void MeshClean(Triangle& triangle); + + std::vector GetTriangles(); std::vector edge_list; @@ -119,8 +121,11 @@ public: private: - std::list tri_list_; - std::vector points_; + std::vector triangles_; + std::list map_; + + Point** points_; + int point_count_; // Advancing front AdvancingFront* front_; @@ -147,7 +152,7 @@ private: inline AdvancingFront* SweepContext::front() { return front_; } -inline int SweepContext::point_count() { return points_.size(); } +inline int SweepContext::point_count() { return point_count_; } inline void SweepContext::set_head(Point* p1) { head_ = p1; } diff --git a/testbed/data/bird.dat b/testbed/data/bird.dat index caa9652..3f76eae 100644 --- a/testbed/data/bird.dat +++ b/testbed/data/bird.dat @@ -272,4 +272,4 @@ 6.20462 5.25418 5.72617 4.80159 5.13134 4.41366 -4.87271 4.16797 \ No newline at end of file +4.87271 4.16797 diff --git a/testbed/data/dude.dat b/testbed/data/dude.dat index 691dc12..7e43f9c 100644 --- a/testbed/data/dude.dat +++ b/testbed/data/dude.dat @@ -91,4 +91,4 @@ 254.28571 604.50504 251.07143 621.11218 250.53571 649.1479 -268.1955 654.36208 \ No newline at end of file +268.1955 654.36208 diff --git a/testbed/main.cc b/testbed/main.cc index e8a8d1b..9ddd802 100644 --- a/testbed/main.cc +++ b/testbed/main.cc @@ -46,12 +46,13 @@ void Init(); void ShutDown(int return_code); void MainLoop(const double zoom); void Draw(const double zoom); - +void ConstrainedColor(bool constrain); + float rotate_y = 0, rotate_z = 0; const float rotations_per_tick = .2; -list triangles; +vector triangles; double StringToDouble(const std::string& s) { std::istringstream i(s); @@ -80,21 +81,12 @@ int main(int argc, char* argv[]) { double y = rand() % (b - a - 1) + a + 1; polyline[i] = Point(x, y); } - - polyline[0] = Point(5, 5); - polyline[1] = Point(-5, 5); - polyline[2] = Point(-5, -5); - polyline[3] = Point(5, -5); - - //Point foo[] = {Point(5, 5.1), Point(-5, 5.2), Point(-5, -5.3), Point(5, -5.4), Point(5.1, 5.5), Point(5, 5.5), - // Point(-5, 5.6), Point(-5, -5.7), Point(5, -5.8), Point(5, 5.9), Point(-5, 5.1), - // Point(-5, -5.11), Point(5, -5.12), Point(5, 5.13), Point(-5, 5.14), Point(-5, -5.15), Point(5, -5.16)}; - + */ string line; ifstream myfile (argv[1]); - vector points; + vector points; if (myfile.is_open()) { while (!myfile.eof()) { getline (myfile,line); @@ -107,7 +99,7 @@ int main(int argc, char* argv[]) { back_inserter >(tokens)); double x = StringToDouble(tokens[0]); double y = StringToDouble(tokens[1]); - points.push_back(Point(x, y)); + points.push_back(new Point(x, y)); } myfile.close(); } else { @@ -119,7 +111,7 @@ int main(int argc, char* argv[]) { Point** polyline = new Point *[num_points]; for(int i = 0; i < num_points; i++) { - polyline[i] = &points[i]; + polyline[i] = points[i]; } Init(); @@ -229,22 +221,41 @@ void Draw(const double zoom) ResetZoom(zoom, center.x, center.y, 800, 600); - list::iterator it; - for (it = triangles.begin(); it != triangles.end(); it++) { - Triangle* t = *it; - Point* a = t->GetPoint(0); - Point* b = t->GetPoint(1); - Point* c = t->GetPoint(2); - - // Red - glColor3f(1, 0, 0); - - glBegin(GL_LINE_LOOP); // Drawing Using Triangles - glVertex2f(a->x, a->y); // Top - glVertex2f(b->x, b->y); // Bottom Left - glVertex2f(c->x, c->y); // Bottom Right - glEnd(); + for (int i = 0; i < triangles.size(); i++) { + Triangle& t = *triangles[i]; + Point& a = *t.GetPoint(0); + Point& b = *t.GetPoint(1); + Point& c = *t.GetPoint(2); + + ConstrainedColor(t.constrained_edge[2]); + glBegin(GL_LINES); + glVertex2f(a.x, a.y); + glVertex2f(b.x, b.y); + glEnd( ); + + ConstrainedColor(t.constrained_edge[0]); + glBegin(GL_LINES); + glVertex2f(b.x, b.y); + glVertex2f(c.x, c.y); + glEnd( ); + + ConstrainedColor(t.constrained_edge[1]); + glBegin(GL_LINES); + glVertex2f(c.x, c.y); + glVertex2f(a.x, a.y); + glEnd( ); + } } + +void ConstrainedColor(bool constrain) { + if(constrain) { + // Green + glColor3f(0, 1, 0); + } else { + // Red + glColor3f(1, 0, 0); + } +}