mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-16 02:32:25 +01:00
added AddHole to api; added random distribution example
This commit is contained in:
parent
7cbc314b7b
commit
8348364612
9
README
9
README
@ -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
|
@ -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_);
|
||||||
|
@ -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
|
||||||
|
@ -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_;
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user