fixed pointer bugs

This commit is contained in:
zzzzrrr 2010-01-22 14:52:28 -05:00
parent 654b838fdb
commit e874c363fb
6 changed files with 72 additions and 80 deletions

8
README
View File

@ -11,8 +11,8 @@ Dependencies
Testbed: Testbed:
- gcc - gcc
- OpenGL - OpenGL
- GLFW (http://glfw.sf.net) - GLFW (http://glfw.sf.net)
- Python - Python
Waf (http://code.google.com/p/waf/) is used to compile the testbed, and Waf (http://code.google.com/p/waf/) is used to compile the testbed, and
the Python waf script (86kb) is included in the repositoty. the Python waf script (86kb) is included in the repositoty.
@ -33,8 +33,8 @@ Windows command line:
running the examples running the examples
---------------------------------------------- ----------------------------------------------
p2t <data file> <zoom> p2t <filename> <center-x> <center-y> <zoom>
Example: Example:
./build/default/p2t testbed/data/dude.dat 1.0 ./p2t dude.dat 300 500 2.0

View File

@ -62,7 +62,7 @@ Orientation Orient2d(Point& pa, Point& pb, Point& pc)
double val = detleft - detright; double val = detleft - detright;
if (val > -EPSILON && val < EPSILON) { if (val > -EPSILON && val < EPSILON) {
return COLLINEAR; return COLLINEAR;
} else if (val > EPSILON) { } else if (val > 0) {
return CCW; return CCW;
} }
return CW; return CW;

View File

@ -40,25 +40,18 @@ AdvancingFront::AdvancingFront(Node& head, Node& tail)
Node* AdvancingFront::LocateNode(const double& x) Node* AdvancingFront::LocateNode(const double& x)
{ {
Node* node = search_node_; Node* node = search_node_;
//printf("L: %p - %p\n", node, node->next);
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) {
//printf("%p - %p\n", node, node->prev);
if (x >= node->value) { if (x >= node->value) {
search_node_ = node; search_node_ = node;
//printf("\nSN1: %p - %p\n", search_node_, search_node_->next);
return node; return node;
} }
} }
} else { } else {
//printf(">: %f - %f\n", x, node->value);
while ((node = node->next) != NULL) { while ((node = node->next) != NULL) {
//printf("%p - %p\n", node, node->next);
if (x < node->value) { if (x < node->value) {
search_node_ = node->prev; search_node_ = node->prev;
//printf("\nSN2: %p - %p\n", search_node_, search_node_->next);
return node->prev; return node->prev;
} }
} }
@ -77,7 +70,6 @@ Node* AdvancingFront::LocatePoint(const Point* point)
const double px = point->x; const double px = point->x;
Node* node = FindSearchNode(px); Node* node = FindSearchNode(px);
const double nx = node->point->x; const double nx = node->point->x;
//printf("LP: %p - %p\n", node, node->next);
if (px == nx) { if (px == nx) {
if (point != node->point) { if (point != node->point) {
@ -92,19 +84,17 @@ Node* AdvancingFront::LocatePoint(const Point* point)
} }
} else if (px < nx) { } else if (px < nx) {
while ((node = node->prev) != NULL) { while ((node = node->prev) != NULL) {
//printf("1 - %p - %p\n", node, node->next);
if (point == node->point) { if (point == node->point) {
break; break;
} }
} }
} else { } else {
while ((node = node->next) != NULL) { while ((node = node->next) != NULL) {
//printf("2 - %p - %p\n", node, node->next);
if (point == node->point) if (point == node->point)
break; break;
} }
} }
search_node_ = node; if(node) search_node_ = node;
return node; return node;
} }

View File

@ -40,20 +40,17 @@ 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);
} }
void Sweep::SweepPoints(SweepContext& tcx) void Sweep::SweepPoints(SweepContext& tcx)
{ {
for (int i = 1; i < tcx.point_count(); i++) { for (int i = 1; i < tcx.point_count(); i++) {
Point& point = *tcx.GetPoint(i); Point& point = *tcx.GetPoint(i);
//printf("%i = %f,%f ", i, point.x, point.y); Node* node = &PointEvent(tcx, point);
Node& node = PointEvent(tcx, point);
//printf("1...");
for (int i = 0; i < point.edge_list.size(); i++) { for (int i = 0; i < point.edge_list.size(); i++) {
EdgeEvent(tcx, point.edge_list[i], node); EdgeEvent(tcx, point.edge_list[i], node);
} }
//printf("2!\n");
} }
} }
@ -96,12 +93,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;
} }
@ -109,7 +106,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);
} }
void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point) void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point)
@ -143,7 +140,7 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl
EdgeEvent(tcx, ep, eq, triangle, point); EdgeEvent(tcx, ep, eq, triangle, point);
} else { } else {
// This triangle crosses constraint so lets flippin start! // This triangle crosses constraint so lets flippin start!
FlipEdgeEvent(tcx, ep, eq, *triangle, point); FlipEdgeEvent(tcx, ep, eq, triangle, point);
} }
} }
@ -174,8 +171,7 @@ Node& Sweep::NewFrontTriangle(SweepContext& tcx, Point& point, Node& node)
new_node->prev = &node; new_node->prev = &node;
node.next->prev = new_node; node.next->prev = new_node;
node.next = new_node; node.next = new_node;
//printf("\n%p - %p - %p | ", new_node->prev, new_node, new_node->next);
//printf("%p - %p - %p\n", node.prev, &node, node.next);
if (!Legalize(tcx, *triangle)) { if (!Legalize(tcx, *triangle)) {
tcx.MapTriangleToNodes(*triangle); tcx.MapTriangleToNodes(*triangle);
} }
@ -507,7 +503,7 @@ void Sweep::FillBasin(SweepContext& tcx, Node& node)
tcx.basin.width = tcx.basin.right_node->point->x - tcx.basin.left_node->point->x; tcx.basin.width = tcx.basin.right_node->point->x - tcx.basin.left_node->point->x;
tcx.basin.left_highest = tcx.basin.left_node->point->y > tcx.basin.right_node->point->y; tcx.basin.left_highest = tcx.basin.left_node->point->y > tcx.basin.right_node->point->y;
FillBasinReq(tcx, *tcx.basin.bottom_node); FillBasinReq(tcx, tcx.basin.bottom_node);
} }
/** /**
@ -517,35 +513,35 @@ void Sweep::FillBasin(SweepContext& tcx, Node& node)
* @param node - bottom_node * @param node - bottom_node
* @param cnt - counter used to alternate on even and odd numbers * @param cnt - counter used to alternate on even and odd numbers
*/ */
void Sweep::FillBasinReq(SweepContext& tcx, Node& node) void Sweep::FillBasinReq(SweepContext& tcx, Node* node)
{ {
// if shallow stop filling // if shallow stop filling
if (IsShallow(tcx, node)) { if (IsShallow(tcx, *node)) {
return; return;
} }
Fill(tcx, node); Fill(tcx, *node);
if (node.prev == tcx.basin.left_node && node.next == tcx.basin.right_node) { if (node->prev == tcx.basin.left_node && node->next == tcx.basin.right_node) {
return; return;
} else if (node.prev == tcx.basin.left_node) { } else if (node->prev == tcx.basin.left_node) {
Orientation o = Orient2d(*node.point, *node.next->point, *node.next->next->point); Orientation o = Orient2d(*node->point, *node->next->point, *node->next->next->point);
if (o == CW) { if (o == CW) {
return; return;
} }
node = *node.next; node = node->next;
} else if (node.next == tcx.basin.right_node) { } else if (node->next == tcx.basin.right_node) {
Orientation o = Orient2d(*node.point, *node.prev->point, *node.prev->prev->point); Orientation o = Orient2d(*node->point, *node->prev->point, *node->prev->prev->point);
if (o == CCW) { if (o == CCW) {
return; return;
} }
node = *node.prev; node = node->prev;
} else { } else {
// Continue with the neighbor node with lowest Y value // Continue with the neighbor node with lowest Y value
if (node.prev->point->y < node.next->point->y) { if (node->prev->point->y < node->next->point->y) {
node = *node.prev; node = node->prev;
} else { } else {
node = *node.next; node = node->next;
} }
} }
@ -569,7 +565,7 @@ bool Sweep::IsShallow(SweepContext& tcx, Node& node)
return false; return false;
} }
void Sweep::FillEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) 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);
@ -578,14 +574,14 @@ 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;
} }
} }
} }
@ -640,14 +636,14 @@ 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;
} }
} }
} }
@ -702,10 +698,10 @@ void Sweep::FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
} }
} }
void Sweep::FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& t, Point& p) void Sweep::FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p)
{ {
Triangle& ot = t.NeighborAcross(p); Triangle& ot = t->NeighborAcross(p);
Point& op = *ot.OppositePoint(t, p); Point& op = *ot.OppositePoint(*t, p);
if (&ot == NULL) { if (&ot == NULL) {
// If we want to integrate the fillEdgeEvent do it here // If we want to integrate the fillEdgeEvent do it here
@ -714,37 +710,35 @@ void Sweep::FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& t,
assert(0); assert(0);
} }
if (InScanArea(p, *t.PointCCW(p), *t.PointCW(p), op)) { if (InScanArea(p, *t->PointCCW(p), *t->PointCW(p), op)) {
// Lets rotate shared edge one vertex CW // Lets rotate shared edge one vertex CW
RotateTrianglePair(t, p, ot, op); RotateTrianglePair(*t, p, ot, op);
tcx.MapTriangleToNodes(t); tcx.MapTriangleToNodes(*t);
tcx.MapTriangleToNodes(ot); tcx.MapTriangleToNodes(ot);
if (p == eq && op == ep) { if (p == eq && op == ep) {
if (eq == *tcx.edge_event.constrained_edge->q && ep == *tcx.edge_event.constrained_edge->p) { if (eq == *tcx.edge_event.constrained_edge->q && ep == *tcx.edge_event.constrained_edge->p) {
t.MarkConstrainedEdge(&ep, &eq); t->MarkConstrainedEdge(&ep, &eq);
ot.MarkConstrainedEdge(&ep, &eq); ot.MarkConstrainedEdge(&ep, &eq);
Legalize(tcx, t); Legalize(tcx, *t);
Legalize(tcx, ot); Legalize(tcx, ot);
} else { } else {
// XXX: I think one of the triangles should be legalized here? // XXX: I think one of the triangles should be legalized here?
} }
} else { } else {
//printf("flip again!\n");
Orientation o = Orient2d(eq, op, ep); Orientation o = Orient2d(eq, op, ep);
t = NextFlipTriangle(tcx, (int)o, t, ot, p, op); t = &NextFlipTriangle(tcx, (int)o, *t, ot, p, op);
FlipEdgeEvent(tcx, ep, eq, t, p); FlipEdgeEvent(tcx, ep, eq, t, p);
} }
} else { } else {
Point& newP = NextFlipPoint(ep, eq, ot, op); Point& newP = NextFlipPoint(ep, eq, ot, op);
FlipScanEdgeEvent(tcx, ep, eq, t, ot, newP); FlipScanEdgeEvent(tcx, ep, eq, *t, ot, newP);
EdgeEvent(tcx, ep, eq, &t, p); EdgeEvent(tcx, ep, eq, t, p);
} }
} }
Triangle& Sweep::NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op) Triangle& Sweep::NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op)
{ {
//printf("enum %i,%i\n", o, CCW);
if (o == CCW) { if (o == CCW) {
// ot is not crossing edge after flip // ot is not crossing edge after flip
int edge_index = ot.EdgeIndex(&p, &op); int edge_index = ot.EdgeIndex(&p, &op);
@ -756,7 +750,7 @@ Triangle& Sweep::NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangl
// t is not crossing edge after flip // t is not crossing edge after flip
int edge_index = t.EdgeIndex(&p, &op); int edge_index = t.EdgeIndex(&p, &op);
//printf("edge_index = %i\n", edge_index);
t.delaunay_edge[edge_index] = true; t.delaunay_edge[edge_index] = true;
Legalize(tcx, t); Legalize(tcx, t);
t.ClearDelunayEdges(); t.ClearDelunayEdges();
@ -793,7 +787,7 @@ void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle&
if (InScanArea(eq, *flip_triangle.PointCCW(eq), *flip_triangle.PointCW(eq), op)) { if (InScanArea(eq, *flip_triangle.PointCCW(eq), *flip_triangle.PointCW(eq), op)) {
// flip with new edge op->eq // flip with new edge op->eq
FlipEdgeEvent(tcx, eq, op, ot, op); FlipEdgeEvent(tcx, eq, op, &ot, op);
// TODO: Actually I just figured out that it should be possible to // TODO: Actually I just figured out that it should be possible to
// improve this by getting the next ot and op before the the above // improve this by getting the next ot and op before the the above
// flip and continue the flipScanEdgeEvent here // flip and continue the flipScanEdgeEvent here

View File

@ -54,7 +54,7 @@ void SweepPoints(SweepContext& tcx);
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);
@ -76,15 +76,15 @@ double BasinAngle(Node& node);
void FillBasin(SweepContext& tcx, Node& node); void FillBasin(SweepContext& tcx, Node& node);
void FillBasinReq(SweepContext& tcx, Node& node); void FillBasinReq(SweepContext& tcx, Node* node);
bool IsShallow(SweepContext& tcx, Node& node); bool IsShallow(SweepContext& tcx, Node& node);
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);
@ -92,7 +92,7 @@ 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);
@ -100,7 +100,7 @@ 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);
Triangle& NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op); Triangle& NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op);

View File

@ -53,6 +53,11 @@ float rotate_y = 0,
rotate_z = 0; rotate_z = 0;
const float rotations_per_tick = .2; const float rotations_per_tick = .2;
/// Screen center x
double cx = 0.0;
/// Screen center y
double cy = 0.0;
/// Constrained triangles /// Constrained triangles
vector<Triangle*> triangles; vector<Triangle*> triangles;
/// Triangle map /// Triangle map
@ -67,12 +72,12 @@ double StringToDouble(const std::string& s)
return x; return x;
} }
bool draw_map = true; bool draw_map = false;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc != 3) { if (argc != 5) {
cout << "Usage: p2t filename zoom" << endl; cout << "Usage: p2t filename centerX centerY zoom" << endl;
return 1; return 1;
} }
@ -91,6 +96,9 @@ int main(int argc, char* argv[])
*/ */
cx = atof(argv[2]);
cy = atof(argv[3]);
string line; string line;
ifstream myfile(argv[1]); ifstream myfile(argv[1]);
vector<Point*> points; vector<Point*> points;
@ -133,7 +141,7 @@ int main(int argc, char* argv[])
triangles = cdt->GetTriangles(); triangles = cdt->GetTriangles();
map = cdt->GetMap(); map = cdt->GetMap();
MainLoop(atof(argv[2])); MainLoop(atof(argv[4]));
delete [] polyline; delete [] polyline;
ShutDown(0); ShutDown(0);
@ -227,7 +235,7 @@ void ResetZoom(double zoom, double cx, double cy, double width, double height)
void Draw(const double zoom) void Draw(const double zoom)
{ {
// reset zoom // reset zoom
Point center = Point(0, 0); Point center = Point(cx, cy);
ResetZoom(zoom, center.x, center.y, 800, 600); ResetZoom(zoom, center.x, center.y, 800, 600);
@ -251,7 +259,7 @@ void Draw(const double zoom)
void DrawMap(const double zoom) void DrawMap(const double zoom)
{ {
// reset zoom // reset zoom
Point center = Point(0, 0); Point center = Point(cx, cy);
ResetZoom(zoom, center.x, center.y, 800, 600); ResetZoom(zoom, center.x, center.y, 800, 600);