Debugging various problems with prepairing input that triangle() can
handle.
This commit is contained in:
parent
accb6a88ff
commit
1cbe332e1c
7 changed files with 117 additions and 60 deletions
|
@ -54,6 +54,9 @@ class FGConstruct {
|
|||
|
||||
private:
|
||||
|
||||
// minimum interior angle for triangulation
|
||||
string angle;
|
||||
|
||||
// paths
|
||||
string work_base;
|
||||
string output_base;
|
||||
|
@ -101,6 +104,10 @@ public:
|
|||
// Destructor
|
||||
~FGConstruct();
|
||||
|
||||
// minimum interior angle for triangulation
|
||||
inline string get_angle() const { return angle; }
|
||||
inline void set_angle( const string s ) { angle = s; }
|
||||
|
||||
// paths
|
||||
inline string get_work_base() const { return work_base; }
|
||||
inline void set_work_base( const string s ) { work_base = s; }
|
||||
|
|
|
@ -167,7 +167,7 @@ void first_triangulate( FGConstruct& c, const FGArray& array,
|
|||
cout << "done building node list and polygons" << endl;
|
||||
|
||||
cout << "ready to do triangulation" << endl;
|
||||
t.run_triangulate( 1 );
|
||||
t.run_triangulate( c.get_angle(), 1 );
|
||||
cout << "finished triangulation" << endl;
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ void second_triangulate( FGConstruct& c, FGTriangle& t ) {
|
|||
cout << "done re building node list and polygons" << endl;
|
||||
|
||||
cout << "ready to do second triangulation" << endl;
|
||||
t.run_triangulate( 2 );
|
||||
t.run_triangulate( c.get_angle(), 2 );
|
||||
cout << "finished second triangulation" << endl;
|
||||
}
|
||||
|
||||
|
@ -461,9 +461,9 @@ void construct_tile( FGConstruct& c ) {
|
|||
// display usage and exit
|
||||
void usage( const string name ) {
|
||||
cout << "Usage: " << name
|
||||
<< " <work_base> <output_base> tile_id" << endl;
|
||||
<< " <min_tri_angle> <work_base> <output_base> tile_id" << endl;
|
||||
cout << "Usage: " << name
|
||||
<< " <work_base> <output_base> center_lon center_lat xdist ydist"
|
||||
<< " <min_tri_angle> <work_base> <output_base> center_lon center_lat xdist ydist"
|
||||
<< endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -474,15 +474,16 @@ main(int argc, char **argv) {
|
|||
|
||||
fglog().setLogLevels( FG_ALL, FG_DEBUG );
|
||||
|
||||
if ( argc < 3 ) {
|
||||
if ( argc < 4 ) {
|
||||
usage( argv[0] );
|
||||
}
|
||||
|
||||
// main construction data management class
|
||||
FGConstruct c;
|
||||
|
||||
c.set_work_base( argv[1] );
|
||||
c.set_output_base( argv[2] );
|
||||
c.set_angle( argv[1] );
|
||||
c.set_work_base( argv[2] );
|
||||
c.set_output_base( argv[3] );
|
||||
|
||||
c.set_min_nodes( 50 );
|
||||
c.set_max_nodes( (int)(FG_MAX_NODES * 0.8) );
|
||||
|
@ -506,20 +507,20 @@ main(int argc, char **argv) {
|
|||
// lon = -76.201239; lat = 36.894606; // KORF (Norfolk, Virginia)
|
||||
// lon = -147.166; lat = 60.9925; // Hale-bop test
|
||||
|
||||
if ( argc == 4 ) {
|
||||
if ( argc == 5 ) {
|
||||
// construct a specific tile and exit
|
||||
|
||||
long index = atoi( argv[3] );
|
||||
long index = atoi( argv[4] );
|
||||
FGBucket b( index );
|
||||
c.set_bucket( b );
|
||||
construct_tile( c );
|
||||
} else if ( argc == 7 ) {
|
||||
} else if ( argc == 8 ) {
|
||||
// build all the tiles in an area
|
||||
|
||||
lon = atof( argv[3] );
|
||||
lat = atof( argv[4] );
|
||||
double xdist = atof( argv[5] );
|
||||
double ydist = atof( argv[6] );
|
||||
lon = atof( argv[4] );
|
||||
lat = atof( argv[5] );
|
||||
double xdist = atof( argv[6] );
|
||||
double ydist = atof( argv[7] );
|
||||
|
||||
double min_x = lon - xdist;
|
||||
double min_y = lat - ydist;
|
||||
|
|
|
@ -110,25 +110,42 @@ long int get_next_task( const string& host, int port, long int last_tile ) {
|
|||
// successfully
|
||||
bool construct_tile( const string& work_base, const string& output_base,
|
||||
const FGBucket& b, const string& result_file ) {
|
||||
string command = "../Main/construct " + work_base + " " + output_base + " "
|
||||
+ b.gen_index_str() + " > " + result_file + " 2>&1";
|
||||
cout << command << endl;
|
||||
double angle = 10.0;
|
||||
bool still_trying = true;
|
||||
|
||||
system( command.c_str() );
|
||||
|
||||
FILE *fp = fopen( result_file.c_str(), "r" );
|
||||
char line[256];
|
||||
while ( fgets( line, 256, fp ) != NULL ) {
|
||||
string line_str = line;
|
||||
line_str = line_str.substr(0, line_str.length() - 1);
|
||||
cout << line_str << endl;
|
||||
if ( line_str == "[Finished successfully]" ) {
|
||||
fclose(fp);
|
||||
return true;
|
||||
while ( still_trying ) {
|
||||
still_trying = false;
|
||||
char angle_str[256];
|
||||
sprintf(angle_str, "%.0f", angle);
|
||||
string command = "../Main/construct ";
|
||||
command += angle_str;
|
||||
command += " " + work_base + " " + output_base + " "
|
||||
+ b.gen_index_str() + " > " + result_file + " 2>&1";
|
||||
cout << command << endl;
|
||||
|
||||
system( command.c_str() );
|
||||
|
||||
FILE *fp = fopen( result_file.c_str(), "r" );
|
||||
char line[256];
|
||||
while ( fgets( line, 256, fp ) != NULL ) {
|
||||
string line_str = line;
|
||||
line_str = line_str.substr(0, line_str.length() - 1);
|
||||
cout << line_str << endl;
|
||||
if ( line_str == "[Finished successfully]" ) {
|
||||
fclose(fp);
|
||||
return true;
|
||||
} else if ( line_str == "Error: Ran out of precision at" ) {
|
||||
if ( angle > 9.0 ) {
|
||||
angle = 5.0;
|
||||
still_trying = true;
|
||||
} else if ( angle > 4.0 ) {
|
||||
angle = 0.0;
|
||||
still_trying = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -273,7 +273,7 @@ static void write_out_data(struct triangulateio *out) {
|
|||
// generates extra nodes for a better triangulation. 2 = second pass
|
||||
// after split/reassem where we don't want any extra nodes generated.
|
||||
|
||||
int FGTriangle::run_triangulate( int pass ) {
|
||||
int FGTriangle::run_triangulate( const string& angle, const int pass ) {
|
||||
FGPolygon poly;
|
||||
Point3D p;
|
||||
struct triangulateio in, out, vorout;
|
||||
|
@ -414,7 +414,11 @@ int FGTriangle::run_triangulate( int pass ) {
|
|||
// use a quality value of 10 (q10) meaning no interior
|
||||
// triangle angles less than 10 degrees
|
||||
// tri_options = "pczAen";
|
||||
tri_options = "pczq10Aen";
|
||||
if ( angle == "0" ) {
|
||||
tri_options = "pczAen";
|
||||
} else {
|
||||
tri_options = "pczq" + angle + "Aen";
|
||||
}
|
||||
// // string tri_options = "pzAen";
|
||||
// // string tri_options = "pczq15S400Aen";
|
||||
} else if ( pass == 2 ) {
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
// generates extra nodes for a better triangulation. 2 = second
|
||||
// pass after split/reassem where we don't want any extra nodes
|
||||
// generated.
|
||||
int run_triangulate( int pass );
|
||||
int run_triangulate( const string& angle, const int pass );
|
||||
|
||||
inline FGTriNodes get_out_nodes() const { return out_nodes; }
|
||||
inline size_t get_out_nodes_size() const { return out_nodes.size(); }
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include <Main/construct_types.hxx>
|
||||
|
||||
|
||||
#define FG_PROXIMITY_EPSILON 0.000001
|
||||
#define FG_PROXIMITY_EPSILON 0.00002
|
||||
#define FG_COURSE_EPSILON 0.0003
|
||||
|
||||
|
||||
|
|
|
@ -47,6 +47,13 @@ int FGTriSegments::unique_add( const FGTriSeg& s )
|
|||
|
||||
// cout << s.get_n1() << "," << s.get_n2() << endl;
|
||||
|
||||
// check if segment has duplicated endpoints
|
||||
if ( s.get_n1() == s.get_n2() ) {
|
||||
cout << "WARNING: ignoring null segment with the same "
|
||||
<< "point for both endpoints" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check if segment already exists
|
||||
current = seg_list.begin();
|
||||
last = seg_list.end();
|
||||
|
@ -77,7 +84,7 @@ void FGTriSegments::unique_divide_and_add( const point_list& nodes,
|
|||
bool found_extra = false;
|
||||
int extra_index = 0;
|
||||
int counter;
|
||||
double m, b, y_err, x_err;
|
||||
double m, m1, b, b1, y_err, x_err, y_err_min, x_err_min;
|
||||
const_point_list_iterator current, last;
|
||||
|
||||
// bool temp = false;
|
||||
|
@ -86,7 +93,12 @@ void FGTriSegments::unique_divide_and_add( const point_list& nodes,
|
|||
// temp = true;
|
||||
// }
|
||||
|
||||
if ( fabs(p0.x() - p1.x()) > 3 * FG_EPSILON ) {
|
||||
double xdist = fabs(p0.x() - p1.x());
|
||||
double ydist = fabs(p0.y() - p1.y());
|
||||
x_err_min = xdist + 1.0;
|
||||
y_err_min = ydist + 1.0;
|
||||
|
||||
if ( xdist > ydist ) {
|
||||
// use y = mx + b
|
||||
|
||||
// sort these in a sensible order
|
||||
|
@ -116,48 +128,64 @@ void FGTriSegments::unique_divide_and_add( const point_list& nodes,
|
|||
|
||||
y_err = fabs(current->y() - (m * current->x() + b));
|
||||
|
||||
if ( y_err < 20 * FG_EPSILON ) {
|
||||
// cout << "FOUND EXTRA SEGMENT NODE (Y)" << endl;
|
||||
// cout << p0 << " < " << *current << " < "
|
||||
// << p1 << endl;
|
||||
if ( y_err < FG_PROXIMITY_EPSILON ) {
|
||||
cout << "FOUND EXTRA SEGMENT NODE (Y)" << endl;
|
||||
cout << p0 << " < " << *current << " < "
|
||||
<< p1 << endl;
|
||||
found_extra = true;
|
||||
extra_index = counter;
|
||||
break;
|
||||
if ( y_err < y_err_min ) {
|
||||
extra_index = counter;
|
||||
y_err_min = y_err;
|
||||
}
|
||||
}
|
||||
}
|
||||
++counter;
|
||||
}
|
||||
} else {
|
||||
// use x = constant
|
||||
// use x = m1 * y + b1
|
||||
|
||||
// cout << "FOUND VERTICLE SEGMENT" << endl;
|
||||
|
||||
// sort these in a sensable order
|
||||
// sort these in a sensible order
|
||||
if ( p0.y() > p1.y() ) {
|
||||
Point3D tmp = p0;
|
||||
p0 = p1;
|
||||
p1 = tmp;
|
||||
}
|
||||
|
||||
// cout << " p0 = " << p0 << " p1 = " << p1 << endl;
|
||||
m1 = (p0.x() - p1.x()) / (p0.y() - p1.y());
|
||||
b1 = p1.x() - m1 * p1.y();
|
||||
|
||||
// bool temp = true;
|
||||
// if ( temp ) {
|
||||
// cout << "xdist = " << xdist << " ydist = " << ydist << endl;
|
||||
// cout << " p0 = " << p0 << " p1 = " << p1 << endl;
|
||||
// cout << " m1 = " << m1 << " b1 = " << b1 << endl;
|
||||
// }
|
||||
|
||||
// cout << " should = 0 = " << fabs(p0.x() - (m1 * p0.y() + b1)) << endl;;
|
||||
// cout << " should = 0 = " << fabs(p1.x() - (m1 * p1.y() + b1)) << endl;;
|
||||
|
||||
current = nodes.begin();
|
||||
last = nodes.end();
|
||||
counter = 0;
|
||||
for ( ; current != last; ++current ) {
|
||||
// cout << counter << endl;
|
||||
if ( (current->y() > (p0.y() + FG_EPSILON))
|
||||
if ( (current->y() > (p0.y() + FG_EPSILON))
|
||||
&& (current->y() < (p1.y() - FG_EPSILON)) ) {
|
||||
x_err = fabs(current->x() - p0.x());
|
||||
// cout << " found a potential point, x err = "
|
||||
// << x_err << endl;
|
||||
if ( x_err < 20 * FG_EPSILON ) {
|
||||
// cout << "FOUND EXTRA SEGMENT NODE (X)" << endl;
|
||||
// cout << p0 << " < " << *current << " < "
|
||||
// << p1 << endl;
|
||||
|
||||
x_err = fabs(current->x() - (m1 * current->y() + b1));
|
||||
|
||||
// if ( temp ) {
|
||||
// cout << " (" << counter << ") x_err = " << x_err << endl;
|
||||
// }
|
||||
|
||||
if ( x_err < FG_PROXIMITY_EPSILON ) {
|
||||
cout << "FOUND EXTRA SEGMENT NODE (X)" << endl;
|
||||
cout << p0 << " < " << *current << " < "
|
||||
<< p1 << endl;
|
||||
found_extra = true;
|
||||
extra_index = counter;
|
||||
break;
|
||||
if ( x_err < x_err_min ) {
|
||||
extra_index = counter;
|
||||
x_err_min = x_err;
|
||||
}
|
||||
}
|
||||
}
|
||||
++counter;
|
||||
|
@ -166,8 +194,8 @@ void FGTriSegments::unique_divide_and_add( const point_list& nodes,
|
|||
|
||||
if ( found_extra ) {
|
||||
// recurse with two sub segments
|
||||
// cout << "dividing " << s.get_n1() << " " << extra_index
|
||||
// << " " << s.get_n2() << endl;
|
||||
cout << "dividing " << s.get_n1() << " " << extra_index
|
||||
<< " " << s.get_n2() << endl;
|
||||
unique_divide_and_add( nodes, FGTriSeg( s.get_n1(), extra_index ) );
|
||||
unique_divide_and_add( nodes, FGTriSeg( extra_index, s.get_n2() ) );
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue