added AddHole to api; added random distribution example

This commit is contained in:
zzzzrrr 2010-02-07 15:46:27 -05:00
parent 7cbc314b7b
commit 8348364612
6 changed files with 117 additions and 57 deletions

9
README
View File

@ -36,9 +36,16 @@ Windows command line:
Running the Examples Running the Examples
---------------------------------------------- ----------------------------------------------
p2t <filename> <center-x> <center-y> <zoom> Load data points from a file:
p2t <filename> <center_x> <center_y> <zoom>
Random distribution of points inside a consrained box:
p2t random <num_points> <box_radius> <zoom>
Examples: Examples:
./p2t dude.dat 300 500 2 ./p2t dude.dat 300 500 2
./p2t nazca_monkey.dat 0 0 9 ./p2t nazca_monkey.dat 0 0 9
./p2t random 10 100 5.0
./p2t random 1000 20000 0.025

View File

@ -43,6 +43,10 @@ void CDT::AddHole(std::vector<Point*> polyline)
sweep_context_->AddHole(polyline); sweep_context_->AddHole(polyline);
} }
void CDT::AddPoint(Point* point) {
sweep_context_->AddPoint(point);
}
void CDT::Triangulate() void CDT::Triangulate()
{ {
sweep_->Triangulate(*sweep_context_); sweep_->Triangulate(*sweep_context_);

View File

@ -42,6 +42,8 @@ public:
CDT(std::vector<Point*> polyline); CDT(std::vector<Point*> polyline);
/// Add a hole /// Add a hole
void AddHole(std::vector<Point*> polyline); void AddHole(std::vector<Point*> polyline);
/// Add a single point
void AddPoint(Point* point);
/// Triangulate points /// Triangulate points
void Triangulate(); void Triangulate();
/// Get Delaunay triangles /// Get Delaunay triangles

View File

@ -53,6 +53,10 @@ void SweepContext::AddHole(std::vector<Point*> polyline)
} }
} }
void SweepContext::AddPoint(Point* point) {
points_.push_back(point);
}
std::vector<Triangle*> SweepContext::GetTriangles() std::vector<Triangle*> SweepContext::GetTriangles()
{ {
return triangles_; return triangles_;

View File

@ -46,43 +46,48 @@ class AdvancingFront;
class SweepContext { class SweepContext {
public: public:
// Constructor /// Constructor
SweepContext(std::vector<Point*> polyline); SweepContext(std::vector<Point*> polyline);
// Destructor /// Destructor
~SweepContext(); ~SweepContext();
void set_head(Point* p1); void set_head(Point* p1);
Point* head(); Point* head();
void set_tail(Point* p1); void set_tail(Point* p1);
Point* tail(); Point* tail();
int point_count(); int point_count();
Node& LocateNode(Point& point); Node& LocateNode(Point& point);
void RemoveNode(Node* node); void RemoveNode(Node* node);
void CreateAdvancingFront(); 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 MapTriangleToNodes(Triangle& t);
void AddToMap(Triangle* triangle); void AddToMap(Triangle* triangle);
Point* GetPoint(const int& index); Point* GetPoint(const int& index);
Point* GetPoints(); Point* GetPoints();
void RemoveFromMap(Triangle* triangle); void RemoveFromMap(Triangle* triangle);
void AddHole(std::vector<Point*> polyline); void AddHole(std::vector<Point*> polyline);
void AddPoint(Point* point);
AdvancingFront* front(); AdvancingFront* front();
void MeshClean(Triangle& triangle); void MeshClean(Triangle& triangle);
std::vector<Triangle*> GetTriangles(); std::vector<Triangle*> GetTriangles();
std::list<Triangle*> GetMap(); std::list<Triangle*> GetMap();
std::vector<Edge*> edge_list; std::vector<Edge*> edge_list;
struct Basin { struct Basin {

View File

@ -49,6 +49,7 @@ void Draw(const double zoom);
void DrawMap(const double zoom); void DrawMap(const double zoom);
void ConstrainedColor(bool constrain); void ConstrainedColor(bool constrain);
double StringToDouble(const std::string& s); double StringToDouble(const std::string& s);
float RandomFloat(float min, float max);
/// Dude hole examples /// Dude hole examples
vector<Point*> CreateHeadHole(); vector<Point*> CreateHeadHole();
@ -72,36 +73,49 @@ vector< vector<Point*> > polylines;
/// Draw the entire triangle map? /// Draw the entire triangle map?
bool draw_map = false; bool draw_map = false;
/// Create a random distribution of points?
bool random_distribution = false;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int num_points = 0, max, min;
double zoom;
if (argc != 5) { 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; return 1;
} }
/* if(string(argv[1]) == "random") {
// initialize random seed: num_points = atoi(argv[2]);
srand ( time(NULL) ); random_distribution = true;
max = atoi(argv[3]);
int a = 0; min = -max;
int b = 2000; cx = cy = 0;
zoom = atof(argv[4]);
for(int i = 0; i < num_points; i++) { } else {
double x = rand() % (b - a - 1) + a + 1; zoom = atof(argv[4]);
double y = rand() % (b - a - 1) + a + 1;
polyline[i] = Point(x, y);
}
*/
cx = atof(argv[2]); cx = atof(argv[2]);
cy = atof(argv[3]); cy = atof(argv[3]);
}
vector<p2t::Point*> 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 // Parse and tokenize data file
string line; string line;
ifstream myfile(argv[1]); ifstream myfile(argv[1]);
vector<p2t::Point*> points;
if (myfile.is_open()) { if (myfile.is_open()) {
while (!myfile.eof()) { while (!myfile.eof()) {
getline(myfile, line); getline(myfile, line);
@ -114,44 +128,62 @@ int main(int argc, char* argv[])
back_inserter<vector<string> >(tokens)); back_inserter<vector<string> >(tokens));
double x = StringToDouble(tokens[0]); double x = StringToDouble(tokens[0]);
double y = StringToDouble(tokens[1]); double y = StringToDouble(tokens[1]);
points.push_back(new Point(x, y)); polyline.push_back(new Point(x, y));
num_points++;
} }
myfile.close(); myfile.close();
} else { } else {
cout << "File not opened" << endl; cout << "File not opened" << endl;
} }
}
cout << "Number of points = " << points.size() << endl; cout << "Number of constrained edges = " << polyline.size() << endl;
polylines.push_back(points); polylines.push_back(polyline);
Init(); Init();
/// /*
/// Perform triangulation * Perform triangulation!
/// */
double init_time = glfwGetTime(); 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]); string s(argv[1]);
if(s.find("dude.dat", 0) != string::npos) { if(s.find("dude.dat", 0) != string::npos) {
// Add head hole // Add head hole
vector<Point*> head_hole = CreateHeadHole(); vector<Point*> head_hole = CreateHeadHole();
num_points += head_hole.size();
cdt->AddHole(head_hole); cdt->AddHole(head_hole);
// Add chest hole // Add chest hole
vector<Point*> chest_hole = CreateChestHole(); vector<Point*> chest_hole = CreateChestHole();
num_points += chest_hole.size();
cdt->AddHole(chest_hole); cdt->AddHole(chest_hole);
polylines.push_back(head_hole); polylines.push_back(head_hole);
polylines.push_back(chest_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(); cdt->Triangulate();
double dt = glfwGetTime() - init_time; double dt = glfwGetTime() - init_time;
@ -159,10 +191,11 @@ int main(int argc, char* argv[])
triangles = cdt->GetTriangles(); triangles = cdt->GetTriangles();
map = cdt->GetMap(); map = cdt->GetMap();
cout << "Number of points = " << num_points << endl;
cout << "Number of triangles = " << triangles.size() << 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); ShutDown(0);
return 0; return 0;
@ -367,3 +400,8 @@ double StringToDouble(const std::string& s)
return 0; return 0;
return x; return x;
} }
float RandomFloat(float min, float max) {
float r = (float)rand() / (float)RAND_MAX;
return min + r * (max - min);
}