1
0
Fork 0

Chasing down a bug in building the contour tree. Also tweaked the remove_dups()

routine in the process.
This commit is contained in:
curt 2000-12-22 02:33:37 +00:00
parent 820b3a6152
commit d44401402e
3 changed files with 63 additions and 40 deletions

View file

@ -1804,12 +1804,14 @@ void build_airport( string airport_raw, string_list& runways_raw,
rwy_polys[k].set_poly( poly ); rwy_polys[k].set_poly( poly );
} }
cout << "add nodes/remove dups base " << endl; cout << "add nodes base " << endl;
base_poly = add_nodes_to_poly( base_poly, tmp_nodes ); base_poly = add_nodes_to_poly( base_poly, tmp_nodes );
// write_polygon( base_poly, "base-add" ); // write_polygon( base_poly, "base-add" );
cout << "remove dups base " << endl;
base_poly = remove_dups( base_poly ); base_poly = remove_dups( base_poly );
cout << "remove bad contours base" << endl;
base_poly = remove_bad_contours( base_poly ); base_poly = remove_bad_contours( base_poly );
// write_polygon( base_poly, "base-final" ); // write_polygon( base_poly, "base-fin" );
// tesselate the polygons and prepair them for final output // tesselate the polygons and prepair them for final output

View file

@ -234,7 +234,7 @@ Point3D calc_point_inside_old( const FGPolygon& p, const int contour,
// basic triangulation of a polygon with out adding points or // basic triangulation of a polygon with out adding points or
// splitting edges // splitting edges, this should triangulate around interior holes.
void polygon_tesselate( const FGPolygon &p, void polygon_tesselate( const FGPolygon &p,
triele_list &elelist, triele_list &elelist,
point_list &out_pts ) point_list &out_pts )
@ -360,6 +360,9 @@ void polygon_tesselate( const FGPolygon &p,
// TEMPORARY // TEMPORARY
write_tri_data(&in); write_tri_data(&in);
/* cout << "Press return to continue:";
char junk;
cin >> junk; */
// Triangulate the points. Switches are chosen to read and write // Triangulate the points. Switches are chosen to read and write
// a PSLG (p), number everything from zero (z), and produce an // a PSLG (p), number everything from zero (z), and produce an
@ -636,6 +639,9 @@ static void contour_tesselate( FGContourNode *node, const FGPolygon &p,
// TEMPORARY // TEMPORARY
write_tri_data(&in); write_tri_data(&in);
/* cout << "Press return to continue:";
char junk;
cin >> junk; */
// Triangulate the points. Switches are chosen to read and write // Triangulate the points. Switches are chosen to read and write
// a PSLG (p), number everything from zero (z), and produce an // a PSLG (p), number everything from zero (z), and produce an
@ -762,7 +768,8 @@ static Point3D point_inside_contour( FGContourNode *node, const FGPolygon &p ) {
contour_tesselate( node, p, hole_polys, hole_pts, elelist, out_pts ); contour_tesselate( node, p, hole_polys, hole_pts, elelist, out_pts );
if ( elelist.size() <= 0 ) { if ( elelist.size() <= 0 ) {
cout << "Error polygon triangulated to zero triangles!" << endl; cout << "Error polygon triangulated to zero triangles!" << endl;
exit(-1); return Point3D( -200, -200, 0 );
// exit(-1);
} }
// find the largest triangle in the group // find the largest triangle in the group
@ -856,7 +863,7 @@ static void build_contour_tree( FGContourNode *node,
if ( avail[i] ) { if ( avail[i] ) {
// must still be an available contour // must still be an available contour
int cur_contour = node->get_contour_num(); int cur_contour = node->get_contour_num();
if ( (cur_contour < 0 ) || p.is_inside( cur_contour, i ) ) { if ( (cur_contour < 0 ) || p.is_inside( i, cur_contour ) ) {
// must be inside the parent (or if the parent is // must be inside the parent (or if the parent is
// the root, add all available non-holes. // the root, add all available non-holes.
cout << " adding contour = " << i << endl; cout << " adding contour = " << i << endl;
@ -880,6 +887,7 @@ static void build_contour_tree( FGContourNode *node,
for ( i = 0; i < node->get_num_kids(); ++i ) { for ( i = 0; i < node->get_num_kids(); ++i ) {
for ( int j = 0; j < node->get_num_kids(); ++j ) { for ( int j = 0; j < node->get_num_kids(); ++j ) {
// cout << "working on kid " << i << ", " << j << endl;
if ( i != j ) { if ( i != j ) {
if ( (node->get_kid(i) != NULL)&&(node->get_kid(j) != NULL) ) { if ( (node->get_kid(i) != NULL)&&(node->get_kid(j) != NULL) ) {
int A = node->get_kid( i )->get_contour_num(); int A = node->get_kid( i )->get_contour_num();
@ -891,8 +899,9 @@ static void build_contour_tree( FGContourNode *node,
// need to remove contour j from the kid list // need to remove contour j from the kid list
avail[ node->get_kid( i ) -> get_contour_num() ] = 1; avail[ node->get_kid( i ) -> get_contour_num() ] = 1;
node->remove_kid( i ); node->remove_kid( i );
cout << "removing kid " << i cout << "removing contour " << A
<< " which is inside of kid " << j << endl; << " which is inside of contour " << B << endl;
continue;
} }
} else { } else {
// one of these kids is already NULL, skip // one of these kids is already NULL, skip
@ -941,41 +950,43 @@ void calc_points_inside( FGPolygon& p ) {
// fixed polygon // fixed polygon
FGPolygon remove_dups( const FGPolygon &poly ) { FGPolygon remove_dups( const FGPolygon &poly ) {
FGPolygon result; FGPolygon result;
point_list contour, new_contour;
result.erase(); result.erase();
for ( int i = 0; i < poly.contours(); ++i ) { FGPolygon tmp = poly;
Point3D last = poly.get_pt( i, poly.contour_size(i) - 1 ); for ( int i = 0; i < tmp.contours(); ++i ) {
bool all_same = true; contour = poly.get_contour( i );
for ( int j = 0; j < poly.contour_size(i); ++j ) { // cout << "testing contour " << i << " size = " << contour.size()
// << " hole = " << poly.get_hole_flag( i ) << endl;
bool have_dups = true;
while ( have_dups ) {
have_dups = false;
new_contour.clear();
Point3D last = contour[ contour.size() - 1 ];
for ( int j = 0; j < (int)contour.size(); ++j ) {
// cout << " " << i << " " << j << endl; // cout << " " << i << " " << j << endl;
Point3D cur = poly.get_pt( i, j ); Point3D cur = contour[j];
if ( cur == last ) { if ( cur == last ) {
// skip have_dups = true;
// cout << "skipping a duplicate point" << endl; // cout << "skipping a duplicate point" << endl;
} else { } else {
result.add_node( i, cur ); new_contour.push_back( cur );
all_same = false;
last = cur; last = cur;
} }
} }
contour = new_contour;
// make sure the last point doesn't equal the previous or the first.
Point3D begin = poly.get_pt( i, 0 );
Point3D end = poly.get_pt( i, poly.contour_size(i) - 1 );
if ( begin == end ) {
// skip
cout << "begin == end!" << endl;
// exit(-1);
} }
if ( !all_same ) { // cout << " final size = " << contour.size() << endl;
if ( contour.size() ) {
int flag = poly.get_hole_flag( i ); int flag = poly.get_hole_flag( i );
result.set_hole_flag( i, flag ); result.add_contour( contour, flag );
} else { } else {
// too small an area ... add a token point to the contour // too small an area ... add a token point to the contour
// to keep other things happy, but this "bad" contour will // to keep other things happy, but this "bad" contour will
// get nuked later // get nuked later
result.add_node( i, begin ); result.add_node( i, poly.get_pt( i, 0 ) );
} }
} }

View file

@ -143,7 +143,7 @@ double FGPolygon::minangle_contour( const int contour ) {
} }
// return true if contour B is inside countour A // return true if contour A is inside countour B
bool FGPolygon::is_inside( int a, int b ) const { bool FGPolygon::is_inside( int a, int b ) const {
// make polygons from each specified contour // make polygons from each specified contour
FGPolygon A, B; FGPolygon A, B;
@ -157,14 +157,24 @@ bool FGPolygon::is_inside( int a, int b ) const {
pl = get_contour( b ); pl = get_contour( b );
B.add_contour( pl, 0 ); B.add_contour( pl, 0 );
// B is "inside" A if the polygon_diff( B, A ) is not null. // cout << "A size = " << A.total_size() << endl;
FGPolygon result = polygon_diff( B, A ); // A.write( "A" );
// cout << "B size = " << B.total_size() << endl;
// B.write( "B" );
// A is "inside" B if the polygon_diff( A, B ) is null.
FGPolygon result = polygon_diff( A, B );
// cout << "result size = " << result.total_size() << endl;
// char junk;
// cin >> junk;
if ( result.contours() == 0 ) { if ( result.contours() == 0 ) {
// cout << " is_inside() result = true" << endl; // cout << " " << a << " is_inside() " << b << endl;
return true; return true;
} }
// cout << " is_inside() result = false" << endl; // cout << " " << a << " not is_inside() " << b << endl;
return false; return false;
} }