bug hunting

This commit is contained in:
zzzzrrr 2010-01-20 15:36:05 -05:00
parent fa9488baca
commit 9202d205df
7 changed files with 95 additions and 144 deletions

View File

@ -50,7 +50,7 @@ struct Point {
Point() { x = 0.0; y = 0.0; } Point() { x = 0.0; y = 0.0; }
/// The edges this point constitutes an upper ending point /// The edges this point constitutes an upper ending point
std::vector<Edge> edge_list; std::vector<Edge*> edge_list;
/// Construct using coordinates. /// Construct using coordinates.
Point(double x, double y) : x(x), y(y) {} Point(double x, double y) : x(x), y(y) {}
@ -92,6 +92,10 @@ struct Point {
return len; return len;
} }
void DebugPrint() {
printf("%f,%f ", x, y);
}
}; };
// Represents a simple polygon's edge // Represents a simple polygon's edge
@ -115,8 +119,8 @@ struct Edge {
} }
} }
q->edge_list.push_back(*this); q->edge_list.push_back(this);
//printf("%i\n", q->edge_list.size());
} }
}; };

View File

@ -30,11 +30,16 @@
*/ */
#include "advancing_front.h" #include "advancing_front.h"
AdvancingFront::AdvancingFront() {
head_ = tail_ = search_node_ = NULL;
}
Node* AdvancingFront::Locate(const double& x) { Node* AdvancingFront::Locate(const double& x) {
Node* node = search_node_; Node* node = search_node_;
if(x < node->value) { if(x < node->value) {
//printf("<: - %f,%f - %p\n", x, node->value, node->next);
while((node = node->prev) != NULL) { while((node = node->prev) != NULL) {
if(x >= node->value) { if(x >= node->value) {
search_node_ = node; search_node_ = node;
@ -42,6 +47,8 @@ Node* AdvancingFront::Locate(const double& x) {
} }
} }
} else { } else {
//printf("%p - %p\n", node, node->next);
//printf(">: %f - %f\n", x, node->value);
while((node = node->next) != NULL) { while((node = node->next) != NULL) {
if(x < node->value) { if(x < node->value) {
search_node_ = node->prev; search_node_ = node->prev;

View File

@ -63,6 +63,7 @@ class AdvancingFront {
public: public:
AdvancingFront();
// Destructor // Destructor
~AdvancingFront(); ~AdvancingFront();

View File

@ -40,7 +40,7 @@ void Sweep::Triangulate(SweepContext& tcx) {
// Sweep points; build mesh // Sweep points; build mesh
SweepPoints(tcx); SweepPoints(tcx);
// Clean up // Clean up
FinalizationPolygon(tcx); //FinalizationPolygon(tcx);
} }
@ -48,7 +48,9 @@ void Sweep::SweepPoints(SweepContext& tcx) {
for(int i = 1; i < tcx.point_count(); i++ ) { for(int i = 1; i < tcx.point_count(); i++ ) {
//printf("%i = ",i);
Point& point = *tcx.GetPoint(i); Point& point = *tcx.GetPoint(i);
//printf("size = %i\n", point.edge_list.size());
Node& node = PointEvent(tcx, point); Node& node = PointEvent(tcx, point);
for(int i = 0; i < point.edge_list.size(); i++) { for(int i = 0; i < point.edge_list.size(); i++) {
@ -98,12 +100,12 @@ Node& Sweep::PointEvent(SweepContext& tcx, Point& point) {
return new_node; return new_node;
} }
void Sweep::EdgeEvent(SweepContext& tcx, Edge& edge, Node& node) { void Sweep::EdgeEvent(SweepContext& tcx, Edge* edge, Node& node) {
tcx.edge_event.constrained_edge = &edge; tcx.edge_event.constrained_edge = edge;
tcx.edge_event.right = edge.p->x > edge.q->x; tcx.edge_event.right = edge->p->x > edge->q->x;
if(IsEdgeSideOfTriangle(*node.triangle, *edge.p, *edge.q)){ if(IsEdgeSideOfTriangle(*node.triangle, *edge->p, *edge->q)){
return; return;
} }
@ -111,7 +113,7 @@ void Sweep::EdgeEvent(SweepContext& tcx, Edge& edge, Node& node) {
// TODO: integrate with flip process might give some better performance // 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 // but for now this avoid the issue with cases that needs both flips and fills
FillEdgeEvent(tcx, edge, node); FillEdgeEvent(tcx, edge, node);
EdgeEvent(tcx, *edge.p, *edge.q , node.triangle, *edge.q); EdgeEvent(tcx, *edge->p, *edge->q , node.triangle, *edge->q);
} }
@ -154,6 +156,7 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl
bool Sweep::IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq) { bool Sweep::IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq) {
int index = triangle.EdgeIndex(&ep, &eq); int index = triangle.EdgeIndex(&ep, &eq);
if(index != -1) { if(index != -1) {
triangle.MarkConstrainedEdge(index); triangle.MarkConstrainedEdge(index);
Triangle* t = triangle.GetNeighbor(index); Triangle* t = triangle.GetNeighbor(index);
@ -179,7 +182,7 @@ Node& Sweep::NewFrontTriangle(SweepContext& tcx, Point& point, Node& node ) {
node.next = new_node; node.next = new_node;
if(!Legalize(tcx, *triangle)) { if(!Legalize(tcx, *triangle)) {
tcx.MapTriangleToNodes(*triangle); tcx.MapTriangleToNodes(*triangle);
} }
return *new_node; return *new_node;
@ -578,69 +581,7 @@ bool Sweep::IsShallow(SweepContext& tcx, Node& node) {
return false; return false;
} }
void Sweep::FinalizationConvexHull(SweepContext& tcx) { void Sweep::FillEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) {
Node& n1 = *tcx.front()->head()->next;
Node& n2 = *n1.next;
Node& n3 = *n2.next;
Point& first = *n1.point;
TurnAdvancingFrontConvex(tcx, n2, n3);
// TODO: implement ConvexHull for lower right and left boundary
// Lower right boundary
first = *tcx.front()->head()->point;
n2 = *tcx.front()->tail()->prev;
Triangle& t1 = *n2.triangle;
Point& p1 = *n2.point;
do {
tcx.RemoveFromMap(&t1);
p1 = *t1.PointCCW(p1);
if(p1 == first) break;
t1 = *t1.NeighborCCW(p1);
} while(true);
// Lower left boundary
first = *tcx.front()->head()->next->point;
p1 = *t1.PointCW(*tcx.front()->head()->point);
t1 = *t1.NeighborCW(*tcx.front()->head()->point);
do {
tcx.RemoveFromMap(&t1);
p1 = *t1.PointCCW(p1);
t1 = *t1.NeighborCCW(p1);
} while(p1 != first);
//tcx.FinalizeTriangulation();
}
void Sweep::TurnAdvancingFrontConvex(SweepContext& tcx, Node& b, Node& c) {
Node& first = b;
while(&c != tcx.front()->tail()) {
if(Orient2d(*b.point, *c.point, *c.next->point) == CCW) {
// [b,c,d] Concave - fill around c
Fill(tcx, c);
c = *c.next;
} else {
// [b,c,d] Convex
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;
} else {
// [a,b,c] Convex - nothing to fill
b = c;
c = *c.next;
}
}
}
}
void Sweep::FillEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) {
if(tcx.edge_event.right) { if(tcx.edge_event.right) {
FillRightAboveEdgeEvent(tcx, edge, node); FillRightAboveEdgeEvent(tcx, edge, node);
@ -650,11 +591,11 @@ void Sweep::FillEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) {
} }
void Sweep::FillRightAboveEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) { void Sweep::FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) {
while(node.next->point->x < edge.p->x) { while(node.next->point->x < edge->p->x) {
// Check if next node is below the edge // Check if next node is below the edge
if(Orient2d(*edge.q, *node.next->point, *edge.p) == CCW) { if(Orient2d(*edge->q, *node.next->point, *edge->p) == CCW) {
FillRightBelowEdgeEvent(tcx, edge, node); FillRightBelowEdgeEvent(tcx, edge, node);
} else { } else {
node = *node.next; node = *node.next;
@ -663,9 +604,9 @@ void Sweep::FillRightAboveEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) {
} }
void Sweep::FillRightBelowEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) { void Sweep::FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) {
if(node.point->x < edge.p->x) { if(node.point->x < edge->p->x) {
if(Orient2d(*node.point, *node.next->point, *node.next->next->point ) == CCW ) { if(Orient2d(*node.point, *node.next->point, *node.next->next->point ) == CCW ) {
// Concave // Concave
FillRightConcaveEdgeEvent(tcx, edge, node ); FillRightConcaveEdgeEvent(tcx, edge, node );
@ -679,12 +620,12 @@ void Sweep::FillRightBelowEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) {
} }
void Sweep::FillRightConcaveEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) { void Sweep::FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) {
Fill(tcx, *node.next); Fill(tcx, *node.next);
if(node.next->point != edge.p) { if(node.next->point != edge->p) {
// Next above or below edge? // Next above or below edge?
if(Orient2d(*edge.q, *node.next->point, *edge.p) == CCW) { if(Orient2d(*edge->q, *node.next->point, *edge->p) == CCW) {
// Below // Below
if(Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) { if(Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {
// Next is concave // Next is concave
@ -697,7 +638,7 @@ void Sweep::FillRightConcaveEdgeEvent(SweepContext& tcx, Edge& edge, Node& node)
} }
void Sweep::FillRightConvexEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) { void Sweep::FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) {
// Next concave or convex? // Next concave or convex?
if(Orient2d(*node.next->point, *node.next->next->point, *node.next->next->next->point ) == CCW) { if(Orient2d(*node.next->point, *node.next->next->point, *node.next->next->next->point ) == CCW) {
@ -706,7 +647,7 @@ void Sweep::FillRightConvexEdgeEvent(SweepContext& tcx, Edge& edge, Node& node)
} else{ } else{
// Convex // Convex
// Next above or below edge? // Next above or below edge?
if(Orient2d(*edge.q, *node.next->next->point, *edge.p) == CCW) { if(Orient2d(*edge->q, *node.next->next->point, *edge->p) == CCW) {
// Below // Below
FillRightConvexEdgeEvent(tcx, edge, *node.next); FillRightConvexEdgeEvent(tcx, edge, *node.next);
} else{ } else{
@ -716,11 +657,11 @@ void Sweep::FillRightConvexEdgeEvent(SweepContext& tcx, Edge& edge, Node& node)
} }
void Sweep::FillLeftAboveEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) { void Sweep::FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) {
while(node.prev->point->x > edge.p->x) { while(node.prev->point->x > edge->p->x) {
// Check if next node is below the edge // Check if next node is below the edge
if(Orient2d(*edge.q, *node.prev->point, *edge.p) == CW) { if(Orient2d(*edge->q, *node.prev->point, *edge->p) == CW) {
FillLeftBelowEdgeEvent(tcx, edge, node); FillLeftBelowEdgeEvent(tcx, edge, node);
} else { } else {
node = *node.prev; node = *node.prev;
@ -729,9 +670,9 @@ void Sweep::FillLeftAboveEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) {
} }
void Sweep::FillLeftBelowEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) { void Sweep::FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) {
if( node.point->x > edge.p->x) { if( node.point->x > edge->p->x) {
if(Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW ) { if(Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW ) {
// Concave // Concave
FillLeftConcaveEdgeEvent(tcx, edge, node); FillLeftConcaveEdgeEvent(tcx, edge, node);
@ -745,7 +686,7 @@ void Sweep::FillLeftBelowEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) {
} }
} }
void Sweep::FillLeftConvexEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) { void Sweep::FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) {
// Next concave or convex? // Next concave or convex?
if(Orient2d(*node.prev->point, *node.prev->prev->point, *node.prev->prev->prev->point) == CW) { if(Orient2d(*node.prev->point, *node.prev->prev->point, *node.prev->prev->prev->point) == CW) {
@ -754,7 +695,7 @@ void Sweep::FillLeftConvexEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) {
} else { } else {
// Convex // Convex
// Next above or below edge? // Next above or below edge?
if(Orient2d(*edge.q, *node.prev->prev->point, *edge.p) == CW) { if(Orient2d(*edge->q, *node.prev->prev->point, *edge->p) == CW) {
// Below // Below
FillLeftConvexEdgeEvent(tcx, edge, *node.prev); FillLeftConvexEdgeEvent(tcx, edge, *node.prev);
} else { } else {
@ -763,12 +704,12 @@ void Sweep::FillLeftConvexEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) {
} }
} }
void Sweep::FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge& edge, Node& node) { void Sweep::FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) {
Fill(tcx, *node.prev); Fill(tcx, *node.prev);
if(node.prev->point != edge.p) { if(node.prev->point != edge->p) {
// Next above or below edge? // Next above or below edge?
if(Orient2d(*edge.q, *node.prev->point, *edge.p) == CW) { if(Orient2d(*edge->q, *node.prev->point, *edge->p) == CW) {
// Below // Below
if(Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) { if(Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) {
// Next is concave // Next is concave

View File

@ -55,7 +55,7 @@ private:
Node& PointEvent(SweepContext& tcx, Point& point); Node& PointEvent(SweepContext& tcx, Point& point);
void EdgeEvent(SweepContext& tcx, Edge& edge, Node& node); void EdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
void EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point); void EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point);
@ -81,29 +81,25 @@ private:
bool IsShallow(SweepContext& tcx, Node& node); bool IsShallow(SweepContext& tcx, Node& node);
void FinalizationConvexHull(SweepContext& tcx);
void TurnAdvancingFrontConvex(SweepContext& tcx, Node& b, Node& c);
bool IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq); bool IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq);
void FillEdgeEvent(SweepContext& tcx, Edge& edge, Node& node); void FillEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
void FillRightAboveEdgeEvent(SweepContext& tcx, Edge& edge, Node& node); void FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
void FillRightBelowEdgeEvent(SweepContext& tcx, Edge& edge, Node& node); void FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
void FillRightConcaveEdgeEvent(SweepContext& tcx, Edge& edge, Node& node); void FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
void FillRightConvexEdgeEvent(SweepContext& tcx, Edge& edge, Node& node); void FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
void FillLeftAboveEdgeEvent(SweepContext& tcx, Edge& edge, Node& node); void FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
void FillLeftBelowEdgeEvent(SweepContext& tcx, Edge& edge, Node& node); void FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
void FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge& edge, Node& node); void FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
void FillLeftConvexEdgeEvent(SweepContext& tcx, Edge& edge, Node& node); void FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
void FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& t, Point& p); void FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& t, Point& p);

View File

@ -57,12 +57,13 @@ void SweepContext::InitTriangulation() {
/* /*
printf("*************************\n"); printf("*************************\n");
for(int i = 0; i < point_count_; i++) { for(int i = 0; i < point_count_; i++) {
printf("%p ", points_[i]); printf("%f,%f ", points_[i]->x, points_[i]->y);
printf("%f,%f\n", points_[i]->x, points_[i]->y); printf("%p\n", points_[i]);
} }
printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
for(int i = 0; i < edge_list.size(); i++) { for(int i = 0; i < edge_list.size(); i++) {
edge_list[i]->p->DebugPrint(); edge_list[i]->q->DebugPrint();
printf("%p, %p\n", edge_list[i]->p, edge_list[i]->q); printf("%p, %p\n", edge_list[i]->p, edge_list[i]->q);
} }
*/ */
@ -78,6 +79,7 @@ void SweepContext::InitEdges(Point** polyline, const int& point_count) {
/* /*
for(int i = 0; i < edge_list.size(); i++) { for(int i = 0; i < edge_list.size(); i++) {
edge_list[i]->p->DebugPrint(); edge_list[i]->q->DebugPrint();
printf("%p, %p\n", edge_list[i]->p, edge_list[i]->q); printf("%p, %p\n", edge_list[i]->p, edge_list[i]->q);
} }
*/ */

View File

@ -66,7 +66,7 @@ double StringToDouble(const std::string& s) {
return x; return x;
} }
bool draw_map = false; bool draw_map = true;
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
@ -150,7 +150,7 @@ void Init()
if (glfwOpenWindow(window_width, window_height, 5, 6, 5, 0, 0, 0, GLFW_WINDOW) != GL_TRUE) if (glfwOpenWindow(window_width, window_height, 5, 6, 5, 0, 0, 0, GLFW_WINDOW) != GL_TRUE)
ShutDown(1); ShutDown(1);
glfwSetWindowTitle("The GLFW Window"); glfwSetWindowTitle("Poly2Tri - C++");
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -240,6 +240,34 @@ void Draw(const double zoom) {
Point& b = *t.GetPoint(1); Point& b = *t.GetPoint(1);
Point& c = *t.GetPoint(2); Point& c = *t.GetPoint(2);
// Red
glColor3f(1, 0, 0);
glBegin(GL_LINE_LOOP);
glVertex2f(a.x, a.y);
glVertex2f(b.x, b.y);
glVertex2f(c.x, c.y);
glEnd();
}
}
void DrawMap(const double zoom) {
// reset zoom
Point center = Point(0, 0);
ResetZoom(zoom, center.x, center.y, 800, 600);
list<Triangle*>::iterator it;
for (it = map.begin(); it != map.end(); it++) {
Triangle& t = **it;
Point& a = *t.GetPoint(0);
Point& b = *t.GetPoint(1);
Point& c = *t.GetPoint(2);
ConstrainedColor(t.constrained_edge[2]); ConstrainedColor(t.constrained_edge[2]);
glBegin(GL_LINES); glBegin(GL_LINES);
glVertex2f(a.x, a.y); glVertex2f(a.x, a.y);
@ -262,34 +290,6 @@ void Draw(const double zoom) {
} }
void DrawMap(const double zoom) {
// reset zoom
Point center = Point(0, 0);
ResetZoom(zoom, center.x, center.y, 800, 600);
list<Triangle*>::iterator it;
for (it = map.begin(); it != map.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);
glVertex2f(a.x, a.y);
glVertex2f(b.x, b.y);
glVertex2f(c.x, c.y);
glEnd();
}
}
void ConstrainedColor(bool constrain) { void ConstrainedColor(bool constrain) {
if(constrain) { if(constrain) {
// Green // Green