From 83483646121e216aa1636ff27426fa18fe862b60 Mon Sep 17 00:00:00 2001 From: zzzzrrr Date: Sun, 7 Feb 2010 15:46:27 -0500 Subject: [PATCH] added AddHole to api; added random distribution example --- README | 11 ++- poly2tri/sweep/cdt.cc | 4 + poly2tri/sweep/cdt.h | 2 + poly2tri/sweep/sweep_context.cc | 4 + poly2tri/sweep/sweep_context.h | 13 ++- testbed/main.cc | 140 ++++++++++++++++++++------------ 6 files changed, 117 insertions(+), 57 deletions(-) diff --git a/README b/README index fb5a611..363ff3d 100644 --- a/README +++ b/README @@ -36,9 +36,16 @@ Windows command line: Running the Examples ---------------------------------------------- -p2t +Load data points from a file: +p2t + +Random distribution of points inside a consrained box: +p2t random Examples: ./p2t dude.dat 300 500 2 - ./p2t nazca_monkey.dat 0 0 9 \ No newline at end of file + ./p2t nazca_monkey.dat 0 0 9 + + ./p2t random 10 100 5.0 + ./p2t random 1000 20000 0.025 \ No newline at end of file diff --git a/poly2tri/sweep/cdt.cc b/poly2tri/sweep/cdt.cc index dcca815..f013e47 100644 --- a/poly2tri/sweep/cdt.cc +++ b/poly2tri/sweep/cdt.cc @@ -43,6 +43,10 @@ void CDT::AddHole(std::vector polyline) sweep_context_->AddHole(polyline); } +void CDT::AddPoint(Point* point) { + sweep_context_->AddPoint(point); +} + void CDT::Triangulate() { sweep_->Triangulate(*sweep_context_); diff --git a/poly2tri/sweep/cdt.h b/poly2tri/sweep/cdt.h index 84c781e..eb007b1 100644 --- a/poly2tri/sweep/cdt.h +++ b/poly2tri/sweep/cdt.h @@ -42,6 +42,8 @@ public: CDT(std::vector polyline); /// Add a hole void AddHole(std::vector polyline); +/// Add a single point +void AddPoint(Point* point); /// Triangulate points void Triangulate(); /// Get Delaunay triangles diff --git a/poly2tri/sweep/sweep_context.cc b/poly2tri/sweep/sweep_context.cc index d3fb3dc..e583143 100644 --- a/poly2tri/sweep/sweep_context.cc +++ b/poly2tri/sweep/sweep_context.cc @@ -53,6 +53,10 @@ void SweepContext::AddHole(std::vector polyline) } } +void SweepContext::AddPoint(Point* point) { + points_.push_back(point); +} + std::vector SweepContext::GetTriangles() { return triangles_; diff --git a/poly2tri/sweep/sweep_context.h b/poly2tri/sweep/sweep_context.h index 80cb3ea..6a64c0d 100644 --- a/poly2tri/sweep/sweep_context.h +++ b/poly2tri/sweep/sweep_context.h @@ -46,43 +46,48 @@ class AdvancingFront; class SweepContext { public: -// Constructor +/// Constructor SweepContext(std::vector polyline); -// Destructor +/// Destructor ~SweepContext(); void set_head(Point* p1); + Point* head(); void set_tail(Point* p1); + Point* tail(); int point_count(); Node& LocateNode(Point& point); + void RemoveNode(Node* node); void CreateAdvancingFront(); -// Try to map a node to all sides of this triangle that don't have a neighbor +/// Try to map a node to all sides of this triangle that don't have a neighbor void MapTriangleToNodes(Triangle& t); void AddToMap(Triangle* triangle); Point* GetPoint(const int& index); + Point* GetPoints(); void RemoveFromMap(Triangle* triangle); void AddHole(std::vector polyline); +void AddPoint(Point* point); + AdvancingFront* front(); void MeshClean(Triangle& triangle); std::vector GetTriangles(); std::list GetMap(); - std::vector edge_list; struct Basin { diff --git a/testbed/main.cc b/testbed/main.cc index 0c9c673..61d0485 100644 --- a/testbed/main.cc +++ b/testbed/main.cc @@ -49,6 +49,7 @@ void Draw(const double zoom); void DrawMap(const double zoom); void ConstrainedColor(bool constrain); double StringToDouble(const std::string& s); +float RandomFloat(float min, float max); /// Dude hole examples vector CreateHeadHole(); @@ -72,86 +73,117 @@ vector< vector > polylines; /// Draw the entire triangle map? bool draw_map = false; +/// Create a random distribution of points? +bool random_distribution = false; int main(int argc, char* argv[]) { + int num_points = 0, max, min; + double zoom; + if (argc != 5) { - cout << "Usage: p2t filename centerX centerY zoom" << endl; + cout << "-== USAGE ==-" << endl; + cout << "Load Data File: p2t filename center_x center_y zoom" << endl; + cout << " Random Points: p2t random num_points width zoom" << endl; return 1; } - - /* - // initialize random seed: - srand ( time(NULL) ); - - int a = 0; - int b = 2000; - - for(int i = 0; i < num_points; i++) { - double x = rand() % (b - a - 1) + a + 1; - double y = rand() % (b - a - 1) + a + 1; - polyline[i] = Point(x, y); - } - */ - - cx = atof(argv[2]); - cy = atof(argv[3]); - // Parse and tokenize data file - string line; - ifstream myfile(argv[1]); - vector points; - if (myfile.is_open()) { - while (!myfile.eof()) { - getline(myfile, line); - if (line.size() == 0) { - break; - } - istringstream iss(line); - vector tokens; - copy(istream_iterator(iss), istream_iterator(), - back_inserter >(tokens)); - double x = StringToDouble(tokens[0]); - double y = StringToDouble(tokens[1]); - points.push_back(new Point(x, y)); - } - myfile.close(); + if(string(argv[1]) == "random") { + num_points = atoi(argv[2]); + random_distribution = true; + max = atoi(argv[3]); + min = -max; + cx = cy = 0; + zoom = atof(argv[4]); } else { - cout << "File not opened" << endl; + zoom = atof(argv[4]); + cx = atof(argv[2]); + cy = atof(argv[3]); + } + + vector polyline; + + if(random_distribution) { + // Create a simple bounding box + polyline.push_back(new Point(min,min)); + polyline.push_back(new Point(min,max)); + polyline.push_back(new Point(max,max)); + polyline.push_back(new Point(max,min)); + } else { + // Load pointset from file + + // Parse and tokenize data file + string line; + ifstream myfile(argv[1]); + if (myfile.is_open()) { + while (!myfile.eof()) { + getline(myfile, line); + if (line.size() == 0) { + break; + } + istringstream iss(line); + vector tokens; + copy(istream_iterator(iss), istream_iterator(), + back_inserter >(tokens)); + double x = StringToDouble(tokens[0]); + double y = StringToDouble(tokens[1]); + polyline.push_back(new Point(x, y)); + num_points++; + } + myfile.close(); + } else { + cout << "File not opened" << endl; + } } - cout << "Number of points = " << points.size() << endl; - polylines.push_back(points); + cout << "Number of constrained edges = " << polyline.size() << endl; + polylines.push_back(polyline); Init(); - /// - /// Perform triangulation - /// + /* + * Perform triangulation! + */ double init_time = glfwGetTime(); - // Step 1 - Create CDT and add primary polyline - CDT* cdt = new CDT(points); + /* + * STEP 1: Create CDT and add primary polyline + * NOTE: polyline must be a simple polygon. The polyline's points + * constitute the polygon's constrained edges! + */ + CDT* cdt = new CDT(polyline); /* - // Step 2 - Add holes if necessary + * STEP 2: Add holes or Steiner points if necessary + */ string s(argv[1]); if(s.find("dude.dat", 0) != string::npos) { // Add head hole vector head_hole = CreateHeadHole(); + num_points += head_hole.size(); cdt->AddHole(head_hole); // Add chest hole vector chest_hole = CreateChestHole(); + num_points += chest_hole.size(); cdt->AddHole(chest_hole); - polylines.push_back(head_hole); polylines.push_back(chest_hole); + } else if (random_distribution) { + max-=1; + min+=1; + srand (time(NULL)); + for(int i = 0; i < num_points; i++) { + double x = RandomFloat(min, max); + double y = RandomFloat(min, max); + cdt->AddPoint(new Point(x, y)); + } } - */ - // Step 3 - Triangulate! + /* + * STEP 3: Triangulate! + */ cdt->Triangulate(); double dt = glfwGetTime() - init_time; @@ -159,10 +191,11 @@ int main(int argc, char* argv[]) triangles = cdt->GetTriangles(); map = cdt->GetMap(); + cout << "Number of points = " << num_points << endl; cout << "Number of triangles = " << triangles.size() << endl; - cout << "Elapsed time (secs) = " << dt << endl; + cout << "Elapsed time (ms) = " << dt*1000.0 << endl; - MainLoop(atof(argv[4])); + MainLoop(zoom); ShutDown(0); return 0; @@ -367,3 +400,8 @@ double StringToDouble(const std::string& s) return 0; return x; } + +float RandomFloat(float min, float max) { + float r = (float)rand() / (float)RAND_MAX; + return min + r * (max - min); +}