mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-30 01:03:30 +01:00
fixed more pointer bugs
This commit is contained in:
parent
d776b54e57
commit
0bb55b95b8
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -43,7 +43,7 @@ void CDT::Triangulate() {
|
||||
sweep_->Triangulate(*sweep_context_);
|
||||
}
|
||||
|
||||
std::list<Triangle*> CDT::GetTriangles() {
|
||||
std::vector<Triangle*> CDT::GetTriangles() {
|
||||
return sweep_context_->GetTriangles();
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
/// Triangulate points
|
||||
void Triangulate();
|
||||
/// Get Delaunay triangles
|
||||
std::list<Triangle*> GetTriangles();
|
||||
std::vector<Triangle*> GetTriangles();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
};
|
||||
|
@ -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<Triangle*> SweepContext::GetTriangles() {
|
||||
return tri_list_;
|
||||
std::vector<Triangle*> 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_;
|
||||
|
@ -80,7 +80,9 @@ public:
|
||||
|
||||
AdvancingFront* front();
|
||||
|
||||
std::list<Triangle*> GetTriangles();
|
||||
void MeshClean(Triangle& triangle);
|
||||
|
||||
std::vector<Triangle*> GetTriangles();
|
||||
|
||||
std::vector<Edge*> edge_list;
|
||||
|
||||
@ -119,8 +121,11 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
std::list<Triangle*> tri_list_;
|
||||
std::vector<Point> points_;
|
||||
std::vector<Triangle*> triangles_;
|
||||
std::list<Triangle*> 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; }
|
||||
|
||||
|
@ -272,4 +272,4 @@
|
||||
6.20462 5.25418
|
||||
5.72617 4.80159
|
||||
5.13134 4.41366
|
||||
4.87271 4.16797
|
||||
4.87271 4.16797
|
||||
|
@ -91,4 +91,4 @@
|
||||
254.28571 604.50504
|
||||
251.07143 621.11218
|
||||
250.53571 649.1479
|
||||
268.1955 654.36208
|
||||
268.1955 654.36208
|
||||
|
@ -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<Triangle*> triangles;
|
||||
vector<Triangle*> 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<Point> points;
|
||||
vector<Point*> points;
|
||||
if (myfile.is_open()) {
|
||||
while (!myfile.eof()) {
|
||||
getline (myfile,line);
|
||||
@ -107,7 +99,7 @@ int main(int argc, char* argv[]) {
|
||||
back_inserter<vector<string> >(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<Triangle*>::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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user