From b18c82c33b658dc912fac24d1a6ec92049d8a5a4 Mon Sep 17 00:00:00 2001 From: curt Date: Mon, 5 Apr 1999 02:16:51 +0000 Subject: [PATCH] Dynamically update "error" until the resulting tile data scales within a lower and upper bounds. --- Main/construct.cxx | 83 +++++++++++++++++++++++++++++++++------- Triangulate/triangle.cxx | 15 +++++++- Triangulate/triangle.hxx | 5 +++ Triangulate/trinodes.hxx | 10 +++++ Triangulate/trisegs.hxx | 7 ++++ 5 files changed, 105 insertions(+), 15 deletions(-) diff --git a/Main/construct.cxx b/Main/construct.cxx index 85227747b..1c5c117a9 100644 --- a/Main/construct.cxx +++ b/Main/construct.cxx @@ -26,6 +26,7 @@ #include // for directory reading #include +#include #include #include @@ -46,15 +47,18 @@ int load_dem(const string& work_base, FGBucket& b, FGArray& array) { if ( ! array.open(dem_path) ) { cout << "ERROR: cannot open " << dem_path << endl; - return 0; } - array.parse(); - array.fit( 200 ); + array.parse( b ); return 1; } +// fit dem nodes, return number of fitted nodes +int fit_dem(FGArray& array, int error) { + return array.fit( error ); +} + // do actual scan of directory and loading of files int actual_load_polys( const string& dir, FGBucket& b, FGClipper& clipper ) { @@ -165,17 +169,65 @@ void construct_tile( const string& work_base, const string& output_base, { cout << "Construct tile, bucket = " << b << endl; + // fit with ever increasing error tolerance until we produce <= + // 80% of max nodes. We should really have the sim end handle + // arbitrarily complex tiles. + + const int min_nodes = 50; + const int max_nodes = (int)(MAX_NODES * 0.8); + + bool acceptable = false; + double error = 200.0; + int count = 0; + // load and fit grid of elevation data FGArray array; load_dem( work_base, b, array ); - // load and clip 2d polygon data - FGClipper clipper; - load_polys( work_base, b, clipper ); - - // triangulate the data for each polygon FGTriangle t; - do_triangulate( array, clipper, t ); + + while ( ! acceptable ) { + // fit the data + array.fit( error ); + + // load and clip 2d polygon data + FGClipper clipper; + load_polys( work_base, b, clipper ); + + // triangulate the data for each polygon + do_triangulate( array, clipper, t ); + + acceptable = true; + + count = t.get_out_nodes_size(); + + if ( (count < min_nodes) && (error >= 25.0) ) { + // reduce error tolerance until number of points exceeds the + // minimum threshold + cout << "produced too few nodes ..." << endl; + + acceptable = false; + + error /= 1.5; + cout << "Setting error to " << error << " and retrying fit." + << endl; + } + + if ( (count > max_nodes) && (error <= 1000.0) ) { + // increase error tolerance until number of points drops below + // the maximum threshold + cout << "produced too many nodes ..." << endl; + + acceptable = false; + + error *= 1.5; + cout << "Setting error to " << error << " and retrying fit." + << endl; + } + } + + cout << "finished fit with error = " << error << " node count = " + << count << endl; // generate the output FGGenOutput output; @@ -207,15 +259,16 @@ main(int argc, char **argv) { // lon = -90.757128; lat = 46.790212; // WI32 // lon = -122.220717; lat = 37.721291; // KOAK // lon = -111.721477; lat = 40.215641; // KPVU - lon = -122.309313; lat = 47.448982; // KSEA + // lon = -122.309313; lat = 47.448982; // KSEA + lon = -148.798131; lat = 63.645099; // AK06 (Danali, AK) - double min_x = lon - 1; + double min_x = lon - 3; double min_y = lat - 1; FGBucket b_min( min_x, min_y ); - FGBucket b_max( lon + 1, lat + 1 ); + FGBucket b_max( lon + 3, lat + 1 ); FGBucket b_omit(550314L); - // FGBucket b(942698L); + // FGBucket b(517745L); // FGBucket b(-146.248360, 61.133950); // construct_tile( work_base, output_base, b ); // exit(0); @@ -245,6 +298,10 @@ main(int argc, char **argv) { // $Log$ +// Revision 1.18 1999/04/05 02:16:51 curt +// Dynamically update "error" until the resulting tile data scales within +// a lower and upper bounds. +// // Revision 1.17 1999/04/03 05:22:57 curt // Found a bug in dividing and adding unique verticle segments which could // cause the triangulator to end up in an infinite loop. Basically the code diff --git a/Triangulate/triangle.cxx b/Triangulate/triangle.cxx index 6ce08c492..38b8bf1ac 100644 --- a/Triangulate/triangle.cxx +++ b/Triangulate/triangle.cxx @@ -44,6 +44,9 @@ FGTriangle::build( const point_list& corner_list, FGTriPoly poly; int index; + in_nodes.clear(); + trisegs.clear(); + // Point3D junkp; // int junkc = 0; // char junkn[256]; @@ -70,6 +73,8 @@ FGTriangle::build( const point_list& corner_list, cout << "prepairing node list and polygons" << endl; for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) { + polylist[i].clear(); + // cout << "area type = " << i << endl; current = gpc_polys.polys[i].begin(); last = gpc_polys.polys[i].end(); @@ -328,7 +333,7 @@ int FGTriangle::run_triangulate() { vorout.normlist = (REAL *) NULL; // Needed only if -v switch used. // TEMPORARY - write_out_data(&in); + // write_out_data(&in); // Triangulate the points. Switches are chosen to read and write // a PSLG (p), preserve the convex hull (c), number everything @@ -343,12 +348,13 @@ int FGTriangle::run_triangulate() { triangulate(tri_options.c_str(), &in, &out, &vorout); // TEMPORARY - // write_out_data(&out); + write_out_data(&out); // now copy the results back into the corresponding FGTriangle // structures // nodes + out_nodes.clear(); for ( int i = 0; i < out.numberofpoints; i++ ) { Point3D p( out.pointlist[2*i], out.pointlist[2*i + 1], 0.0 ); // cout << "point = " << p << endl; @@ -356,6 +362,7 @@ int FGTriangle::run_triangulate() { } // triangles + elelist.clear(); int n1, n2, n3; double attribute; for ( int i = 0; i < out.numberoftriangles; i++ ) { @@ -398,6 +405,10 @@ int FGTriangle::run_triangulate() { // $Log$ +// Revision 1.16 1999/04/05 02:17:11 curt +// Dynamically update "error" until the resulting tile data scales within +// a lower and upper bounds. +// // Revision 1.15 1999/04/03 05:22:58 curt // Found a bug in dividing and adding unique verticle segments which could // cause the triangulator to end up in an infinite loop. Basically the code diff --git a/Triangulate/triangle.hxx b/Triangulate/triangle.hxx index b561bd2c1..676f5056c 100644 --- a/Triangulate/triangle.hxx +++ b/Triangulate/triangle.hxx @@ -84,6 +84,7 @@ public: int run_triangulate(); inline FGTriNodes get_out_nodes() const { return out_nodes; } + inline size_t get_out_nodes_size() const { return out_nodes.size(); } inline triele_list get_elelist() const { return elelist; } }; @@ -92,6 +93,10 @@ public: // $Log$ +// Revision 1.11 1999/04/05 02:17:12 curt +// Dynamically update "error" until the resulting tile data scales within +// a lower and upper bounds. +// // Revision 1.10 1999/03/29 13:11:08 curt // Shuffled stl type names a bit. // Began adding support for tri-fanning (or maybe other arrangments too.) diff --git a/Triangulate/trinodes.hxx b/Triangulate/trinodes.hxx index 6b05a42df..f7c5fdd55 100644 --- a/Triangulate/trinodes.hxx +++ b/Triangulate/trinodes.hxx @@ -62,6 +62,9 @@ public: FGTriNodes( void ); ~FGTriNodes( void ); + // delete all the data out of node_list + inline void clear() { node_list.clear(); } + // Add a point to the point list if it doesn't already exist. // Returns the index (starting at zero) of the point in the list. int unique_add( const Point3D& p ); @@ -79,6 +82,9 @@ public: // return the ith point inline Point3D get_node( int i ) const { return node_list[i]; } + + // return the size of the node list + inline size_t size() const { return node_list.size(); } }; @@ -112,6 +118,10 @@ inline bool FGTriNodes::course_close_enough( const Point3D& p1, // $Log$ +// Revision 1.8 1999/04/05 02:17:13 curt +// Dynamically update "error" until the resulting tile data scales within +// a lower and upper bounds. +// // Revision 1.7 1999/03/29 13:11:10 curt // Shuffled stl type names a bit. // Began adding support for tri-fanning (or maybe other arrangments too.) diff --git a/Triangulate/trisegs.hxx b/Triangulate/trisegs.hxx index 09fd5b921..2766bcf15 100644 --- a/Triangulate/trisegs.hxx +++ b/Triangulate/trisegs.hxx @@ -93,6 +93,9 @@ public: FGTriSegments( void ); ~FGTriSegments( void ); + // delete all the data out of seg_list + inline void clear() { seg_list.clear(); } + // Add a segment to the segment list if it doesn't already exist. // Returns the index (starting at zero) of the segment in the // list. @@ -115,6 +118,10 @@ public: // $Log$ +// Revision 1.4 1999/04/05 02:17:14 curt +// Dynamically update "error" until the resulting tile data scales within +// a lower and upper bounds. +// // Revision 1.3 1999/03/27 05:30:18 curt // Handle corner nodes separately from the rest of the fitted nodes. // Add fitted nodes in after corners and polygon nodes since the fitted nodes