mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-26 15:26:12 +01:00
bug hunting
This commit is contained in:
parent
fa9488baca
commit
9202d205df
@ -50,7 +50,7 @@ struct Point {
|
||||
Point() { x = 0.0; y = 0.0; }
|
||||
|
||||
/// The edges this point constitutes an upper ending point
|
||||
std::vector<Edge> edge_list;
|
||||
std::vector<Edge*> edge_list;
|
||||
|
||||
/// Construct using coordinates.
|
||||
Point(double x, double y) : x(x), y(y) {}
|
||||
@ -92,6 +92,10 @@ struct Point {
|
||||
return len;
|
||||
}
|
||||
|
||||
void DebugPrint() {
|
||||
printf("%f,%f ", x, y);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Represents a simple polygon's edge
|
||||
@ -115,8 +119,8 @@ struct Edge {
|
||||
}
|
||||
}
|
||||
|
||||
q->edge_list.push_back(*this);
|
||||
//printf("%i\n", q->edge_list.size());
|
||||
q->edge_list.push_back(this);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -30,11 +30,16 @@
|
||||
*/
|
||||
#include "advancing_front.h"
|
||||
|
||||
AdvancingFront::AdvancingFront() {
|
||||
head_ = tail_ = search_node_ = NULL;
|
||||
}
|
||||
|
||||
Node* AdvancingFront::Locate(const double& x) {
|
||||
|
||||
Node* node = search_node_;
|
||||
|
||||
if(x < node->value) {
|
||||
//printf("<: - %f,%f - %p\n", x, node->value, node->next);
|
||||
while((node = node->prev) != NULL) {
|
||||
if(x >= node->value) {
|
||||
search_node_ = node;
|
||||
@ -42,6 +47,8 @@ Node* AdvancingFront::Locate(const double& x) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//printf("%p - %p\n", node, node->next);
|
||||
//printf(">: %f - %f\n", x, node->value);
|
||||
while((node = node->next) != NULL) {
|
||||
if(x < node->value) {
|
||||
search_node_ = node->prev;
|
||||
|
@ -63,6 +63,7 @@ class AdvancingFront {
|
||||
|
||||
public:
|
||||
|
||||
AdvancingFront();
|
||||
// Destructor
|
||||
~AdvancingFront();
|
||||
|
||||
|
@ -40,7 +40,7 @@ void Sweep::Triangulate(SweepContext& tcx) {
|
||||
// Sweep points; build mesh
|
||||
SweepPoints(tcx);
|
||||
// Clean up
|
||||
FinalizationPolygon(tcx);
|
||||
//FinalizationPolygon(tcx);
|
||||
|
||||
}
|
||||
|
||||
@ -48,7 +48,9 @@ void Sweep::SweepPoints(SweepContext& tcx) {
|
||||
|
||||
for(int i = 1; i < tcx.point_count(); i++ ) {
|
||||
|
||||
//printf("%i = ",i);
|
||||
Point& point = *tcx.GetPoint(i);
|
||||
//printf("size = %i\n", point.edge_list.size());
|
||||
Node& node = PointEvent(tcx, point);
|
||||
|
||||
for(int i = 0; i < point.edge_list.size(); i++) {
|
||||
@ -98,12 +100,12 @@ Node& Sweep::PointEvent(SweepContext& tcx, Point& point) {
|
||||
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.right = edge.p->x > edge.q->x;
|
||||
tcx.edge_event.constrained_edge = edge;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -111,7 +113,7 @@ void Sweep::EdgeEvent(SweepContext& tcx, Edge& edge, Node& node) {
|
||||
// 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
|
||||
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) {
|
||||
|
||||
int index = triangle.EdgeIndex(&ep, &eq);
|
||||
|
||||
if(index != -1) {
|
||||
triangle.MarkConstrainedEdge(index);
|
||||
Triangle* t = triangle.GetNeighbor(index);
|
||||
@ -179,7 +182,7 @@ Node& Sweep::NewFrontTriangle(SweepContext& tcx, Point& point, Node& node ) {
|
||||
node.next = new_node;
|
||||
|
||||
if(!Legalize(tcx, *triangle)) {
|
||||
tcx.MapTriangleToNodes(*triangle);
|
||||
tcx.MapTriangleToNodes(*triangle);
|
||||
}
|
||||
|
||||
return *new_node;
|
||||
@ -578,69 +581,7 @@ bool Sweep::IsShallow(SweepContext& tcx, Node& node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Sweep::FinalizationConvexHull(SweepContext& tcx) {
|
||||
|
||||
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) {
|
||||
void Sweep::FillEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) {
|
||||
|
||||
if(tcx.edge_event.right) {
|
||||
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
|
||||
if(Orient2d(*edge.q, *node.next->point, *edge.p) == CCW) {
|
||||
if(Orient2d(*edge->q, *node.next->point, *edge->p) == CCW) {
|
||||
FillRightBelowEdgeEvent(tcx, edge, node);
|
||||
} else {
|
||||
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 ) {
|
||||
// Concave
|
||||
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);
|
||||
if(node.next->point != edge.p) {
|
||||
if(node.next->point != edge->p) {
|
||||
// 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
|
||||
if(Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {
|
||||
// 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?
|
||||
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{
|
||||
// Convex
|
||||
// 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
|
||||
FillRightConvexEdgeEvent(tcx, edge, *node.next);
|
||||
} 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
|
||||
if(Orient2d(*edge.q, *node.prev->point, *edge.p) == CW) {
|
||||
if(Orient2d(*edge->q, *node.prev->point, *edge->p) == CW) {
|
||||
FillLeftBelowEdgeEvent(tcx, edge, node);
|
||||
} else {
|
||||
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 ) {
|
||||
// Concave
|
||||
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?
|
||||
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 {
|
||||
// Convex
|
||||
// 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
|
||||
FillLeftConvexEdgeEvent(tcx, edge, *node.prev);
|
||||
} 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);
|
||||
if(node.prev->point != edge.p) {
|
||||
if(node.prev->point != edge->p) {
|
||||
// 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
|
||||
if(Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) {
|
||||
// Next is concave
|
||||
|
@ -55,7 +55,7 @@ private:
|
||||
|
||||
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);
|
||||
|
||||
@ -81,29 +81,25 @@ private:
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -57,12 +57,13 @@ void SweepContext::InitTriangulation() {
|
||||
/*
|
||||
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("%f,%f ", points_[i]->x, points_[i]->y);
|
||||
printf("%p\n", points_[i]);
|
||||
}
|
||||
|
||||
printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
|
||||
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);
|
||||
}
|
||||
*/
|
||||
@ -78,6 +79,7 @@ void SweepContext::InitEdges(Point** polyline, const int& point_count) {
|
||||
|
||||
/*
|
||||
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);
|
||||
}
|
||||
*/
|
||||
|
@ -66,7 +66,7 @@ double StringToDouble(const std::string& s) {
|
||||
return x;
|
||||
}
|
||||
|
||||
bool draw_map = false;
|
||||
bool draw_map = true;
|
||||
|
||||
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)
|
||||
ShutDown(1);
|
||||
|
||||
glfwSetWindowTitle("The GLFW Window");
|
||||
glfwSetWindowTitle("Poly2Tri - C++");
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
@ -240,6 +240,34 @@ void Draw(const double zoom) {
|
||||
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 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]);
|
||||
glBegin(GL_LINES);
|
||||
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) {
|
||||
if(constrain) {
|
||||
// Green
|
||||
|
Loading…
Reference in New Issue
Block a user