From 1cbe332e1c61349c24a5e99d7b5845600a29d028 Mon Sep 17 00:00:00 2001 From: curt Date: Wed, 19 May 1999 02:51:07 +0000 Subject: [PATCH] Debugging various problems with prepairing input that triangle() can handle. --- Tools/Construct/Main/construct.hxx | 7 +++ Tools/Construct/Main/main.cxx | 29 ++++----- Tools/Construct/Parallel/client.cxx | 49 ++++++++++----- Tools/Construct/Triangulate/triangle.cxx | 8 ++- Tools/Construct/Triangulate/triangle.hxx | 2 +- Tools/Construct/Triangulate/trinodes.hxx | 2 +- Tools/Construct/Triangulate/trisegs.cxx | 80 ++++++++++++++++-------- 7 files changed, 117 insertions(+), 60 deletions(-) diff --git a/Tools/Construct/Main/construct.hxx b/Tools/Construct/Main/construct.hxx index d7bf83153..007dfeba7 100644 --- a/Tools/Construct/Main/construct.hxx +++ b/Tools/Construct/Main/construct.hxx @@ -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; } diff --git a/Tools/Construct/Main/main.cxx b/Tools/Construct/Main/main.cxx index f59f67e32..98bc9c765 100644 --- a/Tools/Construct/Main/main.cxx +++ b/Tools/Construct/Main/main.cxx @@ -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 - << " tile_id" << endl; + << " tile_id" << endl; cout << "Usage: " << name - << " center_lon center_lat xdist ydist" + << " 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; diff --git a/Tools/Construct/Parallel/client.cxx b/Tools/Construct/Parallel/client.cxx index 5ae1c3bbd..d4ca29e16 100644 --- a/Tools/Construct/Parallel/client.cxx +++ b/Tools/Construct/Parallel/client.cxx @@ -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; } diff --git a/Tools/Construct/Triangulate/triangle.cxx b/Tools/Construct/Triangulate/triangle.cxx index c8fd5d035..0379eeac3 100644 --- a/Tools/Construct/Triangulate/triangle.cxx +++ b/Tools/Construct/Triangulate/triangle.cxx @@ -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 ) { diff --git a/Tools/Construct/Triangulate/triangle.hxx b/Tools/Construct/Triangulate/triangle.hxx index d56ad54c5..d8df11a43 100644 --- a/Tools/Construct/Triangulate/triangle.hxx +++ b/Tools/Construct/Triangulate/triangle.hxx @@ -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(); } diff --git a/Tools/Construct/Triangulate/trinodes.hxx b/Tools/Construct/Triangulate/trinodes.hxx index b39fcf1a0..99ac34496 100644 --- a/Tools/Construct/Triangulate/trinodes.hxx +++ b/Tools/Construct/Triangulate/trinodes.hxx @@ -37,7 +37,7 @@ #include
-#define FG_PROXIMITY_EPSILON 0.000001 +#define FG_PROXIMITY_EPSILON 0.00002 #define FG_COURSE_EPSILON 0.0003 diff --git a/Tools/Construct/Triangulate/trisegs.cxx b/Tools/Construct/Triangulate/trisegs.cxx index a30f72ca2..b9f34ac32 100644 --- a/Tools/Construct/Triangulate/trisegs.cxx +++ b/Tools/Construct/Triangulate/trisegs.cxx @@ -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 {