1
0
Fork 0

Reversing the order of points causes the area calculation to return a

negative number.  Polygon holes are wound opposite of non-holes.  I was
throwing out holes with area < epsilon (i.e. all holes) ... enough said.
This commit is contained in:
curt 1999-06-10 02:01:09 +00:00
parent 3b51535fc0
commit 20e014a16e
3 changed files with 41 additions and 26 deletions
Tools/Construct

View file

@ -183,7 +183,7 @@ void FGClipper::move_slivers( FGPolygon& in, FGPolygon& out ) {
cout << " area = " << area << endl; cout << " area = " << area << endl;
if ( ((min_angle < angle_cutoff) && (area < area_cutoff)) || if ( ((min_angle < angle_cutoff) && (area < area_cutoff)) ||
(area < area_cutoff / 10.0) ) ( area < area_cutoff / 10.0) )
{ {
cout << " WE THINK IT'S A SLIVER!" << endl; cout << " WE THINK IT'S A SLIVER!" << endl;
@ -192,6 +192,7 @@ void FGClipper::move_slivers( FGPolygon& in, FGPolygon& out ) {
if ( hole_flag ) { if ( hole_flag ) {
// just delete/eliminate/remove sliver holes // just delete/eliminate/remove sliver holes
cout << "just deleting a sliver hole" << endl;
in.delete_contour( i ); in.delete_contour( i );
} else { } else {
// move sliver contour to out polygon // move sliver contour to out polygon
@ -259,6 +260,9 @@ void FGClipper::merge_slivers( FGPolyList& clipped, FGPolygon& slivers ) {
} }
} }
} }
if ( !done ) {
cout << "no suitable polys found for sliver merge" << endl;
}
} }
} }

View file

@ -88,8 +88,19 @@ static double calc_angle(point2d a, point2d b, point2d c) {
// the y value of a point on the line that intersects with the // the y value of a point on the line that intersects with the
// verticle line through x. Return true if an intersection is found, // verticle line through x. Return true if an intersection is found,
// false otherwise. // false otherwise.
static bool intersects( const Point3D& p0, const Point3D& p1, double x, static bool intersects( Point3D p0, Point3D p1, double x, Point3D *result ) {
Point3D *result ) { // sort the end points
if ( p0.x() > p1.x() ) {
Point3D tmp = p0;
p0 = p1;
p1 = tmp;
}
if ( (x < p0.x()) || (x > p1.x()) ) {
// out of range of line segment, bail right away
return false;
}
// equation of a line through (x0,y0) and (x1,y1): // equation of a line through (x0,y0) and (x1,y1):
// //
// y = y1 + (x - x1) * (y0 - y1) / (x0 - x1) // y = y1 + (x - x1) * (y0 - y1) / (x0 - x1)
@ -206,7 +217,7 @@ void FGPolygon::calc_point_inside( const int contour,
p2_index = trinodes.find( p2 ); p2_index = trinodes.find( p2 );
if ( intersects(p1, p2, m.x(), &result) ) { if ( intersects(p1, p2, m.x(), &result) ) {
// cout << "intersection = " << result << endl; cout << "intersection = " << result << endl;
if ( ( result.y() < p3.y() ) && if ( ( result.y() < p3.y() ) &&
( result.y() > m.y() ) && ( result.y() > m.y() ) &&
( base_leg != FGTriSeg(p1_index, p2_index) ) ) { ( base_leg != FGTriSeg(p1_index, p2_index) ) ) {
@ -221,7 +232,7 @@ void FGPolygon::calc_point_inside( const int contour,
p1_index = trinodes.find( p1 ); p1_index = trinodes.find( p1 );
p2_index = trinodes.find( p2 ); p2_index = trinodes.find( p2 );
if ( intersects(p1, p2, m.x(), &result) ) { if ( intersects(p1, p2, m.x(), &result) ) {
// cout << "intersection = " << result << endl; cout << "intersection = " << result << endl;
if ( ( result.y() < p3.y() ) && if ( ( result.y() < p3.y() ) &&
( result.y() > m.y() ) && ( result.y() > m.y() ) &&
( base_leg != FGTriSeg(p1_index, p2_index) ) ) { ( base_leg != FGTriSeg(p1_index, p2_index) ) ) {
@ -259,7 +270,9 @@ double FGPolygon::area_contour( const int contour ) {
sum += c[(i+1)%size].x() * c[i].y() - c[i].x() * c[(i+1)%size].y(); sum += c[(i+1)%size].x() * c[i].y() - c[i].x() * c[(i+1)%size].y();
} }
return sum / 2.0; // area can be negative or positive depending on the polygon
// winding order
return fabs(sum / 2.0);
} }
@ -454,6 +467,3 @@ FGPolygon polygon_xor( const FGPolygon& subject, const FGPolygon& clip ) {
FGPolygon polygon_union( const FGPolygon& subject, const FGPolygon& clip ) { FGPolygon polygon_union( const FGPolygon& subject, const FGPolygon& clip ) {
return polygon_clip( POLY_UNION, subject, clip ); return polygon_clip( POLY_UNION, subject, clip );
} }

View file

@ -41,7 +41,6 @@ FGTriangle::build( const point_list& corner_list,
const FGPolyList& gpc_polys ) const FGPolyList& gpc_polys )
{ {
int debug_counter = 0; int debug_counter = 0;
FGPolygon poly;
int index; int index;
in_nodes.clear(); in_nodes.clear();
@ -75,12 +74,13 @@ FGTriangle::build( const point_list& corner_list,
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) { for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
polylist[i].clear(); polylist[i].clear();
// cout << "area type = " << i << endl; cout << "area type = " << i << endl;
debug_counter = 0; debug_counter = 0;
current = gpc_polys.polys[i].begin(); current = gpc_polys.polys[i].begin();
last = gpc_polys.polys[i].end(); last = gpc_polys.polys[i].end();
for ( ; current != last; ++current ) { for ( ; current != last; ++current ) {
gpc_poly = *current; gpc_poly = *current;
cout << "processing a polygon, contours = " cout << "processing a polygon, contours = "
<< gpc_poly.contours() << endl; << gpc_poly.contours() << endl;
@ -89,10 +89,7 @@ FGTriangle::build( const point_list& corner_list,
exit(-1); exit(-1);
} }
poly.erase();
int j; int j;
for ( j = 0; j < gpc_poly.contours(); ++j ) { for ( j = 0; j < gpc_poly.contours(); ++j ) {
cout << " processing contour = " << j << ", nodes = " cout << " processing contour = " << j << ", nodes = "
<< gpc_poly.contour_size( j ) << ", hole = " << gpc_poly.contour_size( j ) << ", hole = "
@ -106,47 +103,49 @@ FGTriangle::build( const point_list& corner_list,
index = in_nodes.unique_add( p ); index = in_nodes.unique_add( p );
// junkp = in_nodes.get_node( index ); // junkp = in_nodes.get_node( index );
// fprintf(junkfp, "%.4f %.4f\n", junkp.x(), junkp.y()); // fprintf(junkfp, "%.4f %.4f\n", junkp.x(), junkp.y());
poly.add_node(j, p);
// cout << " - " << index << endl; // cout << " - " << index << endl;
} }
// fprintf(junkfp, "%.4f %.4f\n", // fprintf(junkfp, "%.4f %.4f\n",
// gpc_poly->contour[j].vertex[0].x, // gpc_poly->contour[j].vertex[0].x,
// gpc_poly->contour[j].vertex[0].y); // gpc_poly->contour[j].vertex[0].y);
// fclose(junkfp); // fclose(junkfp);
poly.set_hole_flag( j, gpc_poly.get_hole_flag( j ) );
} }
for ( j = 0; j < gpc_poly.contours(); ++j ) { for ( j = 0; j < gpc_poly.contours(); ++j ) {
poly.calc_point_inside( j, in_nodes ); gpc_poly.calc_point_inside( j, in_nodes );
} }
polylist[i].push_back( gpc_poly );
#if 0 #if 0
// temporary ... write out hole/polygon info for debugging // temporary ... write out hole/polygon info for debugging
for ( j = 0; j < (int)poly.contours(); ++j ) { for ( j = 0; j < (int)gpc_poly.contours(); ++j ) {
char pname[256]; char pname[256];
sprintf(pname, "poly%02d-%02d-%02d", i, debug_counter, j); sprintf(pname, "poly%02d-%02d-%02d", i, debug_counter, j);
cout << "writing to " << pname << endl;
FILE *fp = fopen( pname, "w" ); FILE *fp = fopen( pname, "w" );
Point3D point; Point3D point;
for ( int k = 0; k < poly.contour_size( j ); ++k ) { for ( int k = 0; k < gpc_poly.contour_size( j ); ++k ) {
point = poly.get_pt( j, k ); point = gpc_poly.get_pt( j, k );
fprintf( fp, "%.6f %.6f\n", point.x(), point.y() ); fprintf( fp, "%.6f %.6f\n", point.x(), point.y() );
} }
point = poly.get_pt( j, 0 ); point = gpc_poly.get_pt( j, 0 );
fprintf( fp, "%.6f %.6f\n", point.x(), point.y() ); fprintf( fp, "%.6f %.6f\n", point.x(), point.y() );
fclose(fp); fclose(fp);
char hname[256]; char hname[256];
sprintf(hname, "hole%02d-%02d-%02d", i, debug_counter, j); sprintf(hname, "hole%02d-%02d-%02d", i, debug_counter, j);
FILE *fh = fopen( hname, "w" ); FILE *fh = fopen( hname, "w" );
point = poly.get_point_inside( j ); point = gpc_poly.get_point_inside( j );
fprintf( fh, "%.6f %.6f\n", point.x(), point.y() ); fprintf( fh, "%.6f %.6f\n", point.x(), point.y() );
fclose(fh); fclose(fh);
} }
// cout << "type a letter + enter to continue: ";
// string input;
// cin >> input;
#endif #endif
polylist[i].push_back( poly );
++debug_counter; ++debug_counter;
} }
} }
@ -172,6 +171,8 @@ FGTriangle::build( const point_list& corner_list,
int i1, i2; int i1, i2;
Point3D p1, p2; Point3D p1, p2;
point_list node_list = in_nodes.get_node_list(); point_list node_list = in_nodes.get_node_list();
FGPolygon poly;
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) { for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
cout << "area type = " << i << endl; cout << "area type = " << i << endl;
poly_list_iterator tp_current, tp_last; poly_list_iterator tp_current, tp_last;