1
0
Fork 0

Instead of snapping whenever clipper converts a poly, just snap before clipping,

and after  intermediate nodes are added.
If we snap before intermediate nodes are added, we generate extra slivers, as
the proximity for node insertion may fail when the extra node is snapped away
from the line we are checking
This commit is contained in:
Peter Sadrozinski 2012-03-10 17:38:03 -05:00 committed by Christian Schmitt
parent effbefde41
commit cbea4335f4
11 changed files with 64 additions and 52 deletions

View file

@ -27,6 +27,7 @@
#include <Output/output.hxx> #include <Output/output.hxx>
#include "global.hxx"
#include "elevations.hxx" #include "elevations.hxx"
@ -773,12 +774,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
for ( unsigned int k = 0; k < rwy_polys.size(); ++k ) for ( unsigned int k = 0; k < rwy_polys.size(); ++k )
{ {
TGPolygon poly = rwy_polys[k].get_poly(); TGPolygon poly = rwy_polys[k].get_poly();
poly = snap(poly, gSnap);
rwy_polys[k].set_poly( poly ); rwy_polys[k].set_poly( poly );
} }
for ( unsigned int k = 0; k < pvmt_polys.size(); ++k ) for ( unsigned int k = 0; k < pvmt_polys.size(); ++k )
{ {
TGPolygon poly = pvmt_polys[k].get_poly(); TGPolygon poly = pvmt_polys[k].get_poly();
poly = snap(poly, gSnap);
pvmt_polys[k].set_poly( poly ); pvmt_polys[k].set_poly( poly );
} }
@ -808,6 +811,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, " tmp_feat_nodes size = " << tmp_feat_nodes.get_node_list().size()); SG_LOG(SG_GENERAL, SG_DEBUG, " tmp_feat_nodes size = " << tmp_feat_nodes.get_node_list().size());
base_poly = add_nodes_to_poly( base_poly, tmp_pvmt_nodes ); base_poly = add_nodes_to_poly( base_poly, tmp_pvmt_nodes );
base_poly = snap( base_poly, gSnap );
SG_LOG(SG_GENERAL, SG_DEBUG, " after adding tmp_nodes: " << base_poly); SG_LOG(SG_GENERAL, SG_DEBUG, " after adding tmp_nodes: " << base_poly);
// Finally find slivers in base // Finally find slivers in base

View file

@ -8,6 +8,7 @@
#include <Polygon/chop.hxx> #include <Polygon/chop.hxx>
#include <Geometry/poly_support.hxx> #include <Geometry/poly_support.hxx>
#include "global.hxx"
#include "beznode.hxx" #include "beznode.hxx"
#include "closedpoly.hxx" #include "closedpoly.hxx"
@ -277,7 +278,6 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
// add the pavement vertex // add the pavement vertex
// convert from lat/lon to geo // convert from lat/lon to geo
// (maybe later) - check some simgear objects... // (maybe later) - check some simgear objects...
curLoc.snap();
dst->push_back( curLoc ); dst->push_back( curLoc );
if (p==0) if (p==0)
@ -303,7 +303,6 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
nextLoc = CalculateLinearLocation( curNode->GetLoc(), nextNode->GetLoc(), (1.0f/num_segs) * (p+1) ); nextLoc = CalculateLinearLocation( curNode->GetLoc(), nextNode->GetLoc(), (1.0f/num_segs) * (p+1) );
// add the feature vertex // add the feature vertex
curLoc.snap();
dst->push_back( curLoc ); dst->push_back( curLoc );
if (p==0) if (p==0)
@ -324,7 +323,6 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
nextLoc = nextNode->GetLoc(); nextLoc = nextNode->GetLoc();
// just add the one vertex - dist is small // just add the one vertex - dist is small
curLoc.snap();
dst->push_back( curLoc ); dst->push_back( curLoc );
SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")"); SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")");
@ -363,6 +361,8 @@ void ClosedPoly::Finish()
ConvertContour( holes[i], &dst_contour ); ConvertContour( holes[i], &dst_contour );
pre_tess.add_contour( dst_contour, 1 ); pre_tess.add_contour( dst_contour, 1 );
} }
pre_tess = snap( pre_tess, gSnap );
} }
// save memory by deleting unneeded resources // save memory by deleting unneeded resources
@ -441,10 +441,10 @@ int ClosedPoly::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams,
TGTexParams tp; TGTexParams tp;
TGPolygon clipped = tgPolygonDiffClipper( pre_tess, *accum ); TGPolygon clipped = tgPolygonDiffClipper( pre_tess, *accum );
SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours());
tgPolygonFindSlivers( clipped, slivers ); tgPolygonFindSlivers( clipped, slivers );
SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours());
sp.erase(); sp.erase();
sp.set_poly( clipped ); sp.set_poly( clipped );
sp.set_material( material ); sp.set_material( material );
@ -453,6 +453,7 @@ int ClosedPoly::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams,
rwy_polys->push_back( sp ); rwy_polys->push_back( sp );
*accum = tgPolygonUnionClipper( pre_tess, *accum ); *accum = tgPolygonUnionClipper( pre_tess, *accum );
// *accum = tgPolygonUnionClipper( clipped, *accum );
/* If debugging this poly, write the poly, and clipped poly and the accum buffer into their own layers */ /* If debugging this poly, write the poly, and clipped poly and the accum buffer into their own layers */
if (ds_id) { if (ds_id) {

View file

@ -28,6 +28,9 @@
extern int nudge; extern int nudge;
// Each polygon vertex is snapped to a grid with this resolution (~1cm by default)
extern double gSnap;
// Final grid size for airport surface (in meters) // Final grid size for airport surface (in meters)
const double coarse_grid = 300.0; const double coarse_grid = 300.0;

View file

@ -18,6 +18,8 @@
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_geodesy.hxx> #include <simgear/math/sg_geodesy.hxx>
#include <Geometry/poly_support.hxx>
#include "global.hxx" #include "global.hxx"
#include "apt_math.hxx" #include "apt_math.hxx"
#include "helipad.hxx" #include "helipad.hxx"
@ -61,12 +63,18 @@ void Helipad::gen_helipad( const TGPolygon& runway,
Point3D a2 = runway.get_pt(0, 0); Point3D a2 = runway.get_pt(0, 0);
Point3D a3 = runway.get_pt(0, 3); Point3D a3 = runway.get_pt(0, 3);
#if 0
if ( startl_pct > 0.0 ) { if ( startl_pct > 0.0 ) {
startl_pct -= nudge * SG_EPSILON; startl_pct -= nudge * SG_EPSILON;
} }
if ( endl_pct < 1.0 ) { if ( endl_pct < 1.0 ) {
endl_pct += nudge * SG_EPSILON; endl_pct += nudge * SG_EPSILON;
} }
#endif
if ( startl_pct < 0.0 ) {
startl_pct = 0.0;
}
if ( endl_pct > 1.0 ) { if ( endl_pct > 1.0 ) {
endl_pct = 1.0; endl_pct = 1.0;
@ -77,6 +85,7 @@ void Helipad::gen_helipad( const TGPolygon& runway,
// with our polygon clipping code. This attempts to compensate // with our polygon clipping code. This attempts to compensate
// for that by nudging the areas a bit bigger so we don't end up // for that by nudging the areas a bit bigger so we don't end up
// with polygon slivers. // with polygon slivers.
#if 0
if ( startw_pct > 0.0 || endw_pct < 1.0 ) { if ( startw_pct > 0.0 || endw_pct < 1.0 ) {
if ( startw_pct > 0.0 ) { if ( startw_pct > 0.0 ) {
startw_pct -= nudge * SG_EPSILON; startw_pct -= nudge * SG_EPSILON;
@ -85,6 +94,7 @@ void Helipad::gen_helipad( const TGPolygon& runway,
endw_pct += nudge * SG_EPSILON; endw_pct += nudge * SG_EPSILON;
} }
} }
#endif
SG_LOG(SG_GENERAL, SG_DEBUG, "start len % = " << startl_pct SG_LOG(SG_GENERAL, SG_DEBUG, "start len % = " << startl_pct
<< " end len % = " << endl_pct); << " end len % = " << endl_pct);
@ -138,6 +148,7 @@ void Helipad::gen_helipad( const TGPolygon& runway,
section.add_node( 0, p0 ); section.add_node( 0, p0 );
section.add_node( 0, p1 ); section.add_node( 0, p1 );
section.add_node( 0, p3 ); section.add_node( 0, p3 );
section = snap( section, gSnap );
// print runway points // print runway points
SG_LOG(SG_GENERAL, SG_DEBUG, "pre clipped runway pts " << prefix << material); SG_LOG(SG_GENERAL, SG_DEBUG, "pre clipped runway pts " << prefix << material);
@ -149,12 +160,7 @@ void Helipad::gen_helipad( const TGPolygon& runway,
} }
// Clip the new polygon against what ever has already been created. // Clip the new polygon against what ever has already been created.
#if 0
TGPolygon clipped = tgPolygonDiff( section, *accum );
#else
TGPolygon clipped = tgPolygonDiffClipper( section, *accum ); TGPolygon clipped = tgPolygonDiffClipper( section, *accum );
#endif
tgPolygonFindSlivers( clipped, slivers ); tgPolygonFindSlivers( clipped, slivers );
// Split long edges to create an object that can better flow with // Split long edges to create an object that can better flow with
@ -170,11 +176,7 @@ void Helipad::gen_helipad( const TGPolygon& runway,
rwy_polys->push_back( sp ); rwy_polys->push_back( sp );
SG_LOG(SG_GENERAL, SG_DEBUG, "section = " << clipped.contours()); SG_LOG(SG_GENERAL, SG_DEBUG, "section = " << clipped.contours());
#if 0
*accum = tgPolygonUnion( section, *accum );
#else
*accum = tgPolygonUnionClipper( section, *accum ); *accum = tgPolygonUnionClipper( section, *accum );
#endif
// Store away what we need to know for texture coordinate // Store away what we need to know for texture coordinate
// calculation. (CLO 10/20/02: why can't we calculate texture // calculation. (CLO 10/20/02: why can't we calculate texture
@ -292,9 +294,11 @@ void Helipad::BuildBtg( superpoly_list *rwy_polys,
{ {
TGPolygon base, safe_base; TGPolygon base, safe_base;
base = gen_runway_area_w_extend( 0.0, maxsize * 0.25 , 0.0, 0.0, maxsize * 0.25 ); base = gen_runway_area_w_extend( 0.0, maxsize * 0.25 , 0.0, 0.0, maxsize * 0.25 );
base = snap( base, gSnap );
// also clear a safe area around the pad // also clear a safe area around the pad
safe_base = gen_runway_area_w_extend( 0.0, maxsize * 0.5, 0.0, 0.0, maxsize * 0.5 ); safe_base = gen_runway_area_w_extend( 0.0, maxsize * 0.5, 0.0, 0.0, maxsize * 0.5 );
safe_base = snap( safe_base, gSnap );
// add this to the airport clearing // add this to the airport clearing
*apt_clearing = tgPolygonUnionClipper(safe_base, *apt_clearing); *apt_clearing = tgPolygonUnionClipper(safe_base, *apt_clearing);

View file

@ -9,6 +9,7 @@
// for debugging clipping errors // for debugging clipping errors
#include <Polygon/chop.hxx> #include <Polygon/chop.hxx>
#include "global.hxx"
#include "beznode.hxx" #include "beznode.hxx"
#include "linearfeature.hxx" #include "linearfeature.hxx"
#include "math.h" #include "math.h"
@ -742,8 +743,6 @@ int LinearFeature::Finish( bool closed, unsigned int idx )
cur_outer = OffsetPointMiddle( &points[j-1], &points[j], &points[j+1], offset-width/2.0f ); cur_outer = OffsetPointMiddle( &points[j-1], &points[j], &points[j+1], offset-width/2.0f );
cur_inner = OffsetPointMiddle( &points[j-1], &points[j], &points[j+1], offset+width/2.0f ); cur_inner = OffsetPointMiddle( &points[j-1], &points[j], &points[j+1], offset+width/2.0f );
} }
cur_outer.snap();
cur_inner.snap();
if ( (prev_inner.x() != 0.0f) && (prev_inner.y() != 0.0f) ) if ( (prev_inner.x() != 0.0f) && (prev_inner.y() != 0.0f) )
{ {
@ -756,6 +755,7 @@ int LinearFeature::Finish( bool closed, unsigned int idx )
poly.add_node( 0, prev_outer ); poly.add_node( 0, prev_outer );
poly.add_node( 0, cur_outer ); poly.add_node( 0, cur_outer );
poly.add_node( 0, cur_inner ); poly.add_node( 0, cur_inner );
poly = snap( poly, gSnap );
#if DEBUG_LF #if DEBUG_LF
char feature_name[128]; char feature_name[128];

View file

@ -112,8 +112,9 @@ static void help( int argc, char **argv, const string_list& elev_src ) {
} }
// TODO: where do these belong // TODO: where do these belong
int nudge = 10; int nudge = 0;
double slope_max = 0.2; double slope_max = 0.2;
double gSnap = 0.0000001;
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
@ -172,6 +173,10 @@ int main(int argc, char **argv)
else if ( arg.find("--nudge=") == 0 ) else if ( arg.find("--nudge=") == 0 )
{ {
nudge = atoi( arg.substr(8).c_str() ); nudge = atoi( arg.substr(8).c_str() );
}
else if ( arg.find("--snap=") == 0 )
{
gSnap = atof( arg.substr(7).c_str() );
} }
else if ( arg.find("--last_apt_file=") == 0 ) else if ( arg.find("--last_apt_file=") == 0 )
{ {

View file

@ -8,6 +8,7 @@
#include <Geometry/poly_support.hxx> #include <Geometry/poly_support.hxx>
#include <Polygon/polygon.hxx> #include <Polygon/polygon.hxx>
#include "global.hxx"
#include "apt_math.hxx" #include "apt_math.hxx"
#include "beznode.hxx" #include "beznode.hxx"
#include "runway.hxx" #include "runway.hxx"
@ -166,9 +167,11 @@ int Runway::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, supe
// generate area around runways // generate area around runways
base = gen_runway_area_w_extend( 20.0, -rwy.overrun[0], -rwy.overrun[1], 20.0 ); base = gen_runway_area_w_extend( 20.0, -rwy.overrun[0], -rwy.overrun[1], 20.0 );
base = snap( base, gSnap );
// also clear a safe area around the runway // also clear a safe area around the runway
safe_base = gen_runway_area_w_extend( 180.0, -rwy.overrun[0], -rwy.overrun[1], 50.0 ); safe_base = gen_runway_area_w_extend( 180.0, -rwy.overrun[0], -rwy.overrun[1], 50.0 );
safe_base = snap( safe_base, gSnap );
// add this to the airport clearing // add this to the airport clearing
*apt_clearing = tgPolygonUnionClipper( safe_base, *apt_clearing ); *apt_clearing = tgPolygonUnionClipper( safe_base, *apt_clearing );

View file

@ -24,6 +24,8 @@
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_geodesy.hxx> #include <simgear/math/sg_geodesy.hxx>
#include <Geometry/poly_support.hxx>
#include "global.hxx" #include "global.hxx"
#include "beznode.hxx" #include "beznode.hxx"
#include "runway.hxx" #include "runway.hxx"
@ -107,12 +109,18 @@ void Runway::gen_runway_section( const TGPolygon& runway,
Point3D a2 = runway.get_pt(0, 0); Point3D a2 = runway.get_pt(0, 0);
Point3D a3 = runway.get_pt(0, 3); Point3D a3 = runway.get_pt(0, 3);
#if 0
if ( startl_pct > 0.0 ) { if ( startl_pct > 0.0 ) {
startl_pct -= nudge * SG_EPSILON; startl_pct -= nudge * SG_EPSILON;
} }
if ( endl_pct < 1.0 ) { if ( endl_pct < 1.0 ) {
endl_pct += nudge * SG_EPSILON; endl_pct += nudge * SG_EPSILON;
} }
#endif
if ( startl_pct < 0.0 ) {
startl_pct = 0.0;
}
if ( endl_pct > 1.0 ) { if ( endl_pct > 1.0 ) {
endl_pct = 1.0; endl_pct = 1.0;
@ -123,6 +131,7 @@ void Runway::gen_runway_section( const TGPolygon& runway,
// with our polygon clipping code. This attempts to compensate // with our polygon clipping code. This attempts to compensate
// for that by nudging the areas a bit bigger so we don't end up // for that by nudging the areas a bit bigger so we don't end up
// with polygon slivers. // with polygon slivers.
#if 0
if ( startw_pct > 0.0 || endw_pct < 1.0 ) { if ( startw_pct > 0.0 || endw_pct < 1.0 ) {
if ( startw_pct > 0.0 ) { if ( startw_pct > 0.0 ) {
startw_pct -= nudge * SG_EPSILON; startw_pct -= nudge * SG_EPSILON;
@ -131,6 +140,7 @@ void Runway::gen_runway_section( const TGPolygon& runway,
endw_pct += nudge * SG_EPSILON; endw_pct += nudge * SG_EPSILON;
} }
} }
#endif
SG_LOG(SG_GENERAL, SG_DEBUG, "start len % = " << startl_pct SG_LOG(SG_GENERAL, SG_DEBUG, "start len % = " << startl_pct
<< " end len % = " << endl_pct); << " end len % = " << endl_pct);
@ -184,6 +194,7 @@ void Runway::gen_runway_section( const TGPolygon& runway,
section.add_node( 0, p0 ); section.add_node( 0, p0 );
section.add_node( 0, p1 ); section.add_node( 0, p1 );
section.add_node( 0, p3 ); section.add_node( 0, p3 );
section = snap( section, gSnap );
// print runway points // print runway points
SG_LOG(SG_GENERAL, SG_DEBUG, "pre clipped runway pts " << material_prefix << material); SG_LOG(SG_GENERAL, SG_DEBUG, "pre clipped runway pts " << material_prefix << material);

View file

@ -50,9 +50,6 @@
//const double fgPoint3_Epsilon = 0.0000001; //const double fgPoint3_Epsilon = 0.0000001;
const double fgPoint3_Epsilon = 0.000001; const double fgPoint3_Epsilon = 0.000001;
#define DO_SNAP 0
#define SNAP_GRID (0.0000001)
enum {PX, PY, PZ}; // axes enum {PX, PY, PZ}; // axes
// Kludge for msvc++ 6.0 - requires forward decls of friend functions. // Kludge for msvc++ 6.0 - requires forward decls of friend functions.
@ -104,7 +101,7 @@ public:
void setradius(const double z); void setradius(const double z);
void setelev(const double z); void setelev(const double z);
void snap(void); void snap( double grid );
// Queries // Queries
@ -339,11 +336,11 @@ inline void Point3D::setelev(const double z) {
n[PZ] = z; n[PZ] = z;
} }
inline void Point3D::snap( void ) inline void Point3D::snap( double grid )
{ {
n[PX] = SNAP_GRID * round( n[PX]/SNAP_GRID ); n[PX] = grid * round( n[PX]/grid );
n[PY] = SNAP_GRID * round( n[PY]/SNAP_GRID ); n[PY] = grid * round( n[PY]/grid );
n[PZ] = SNAP_GRID * round( n[PZ]/SNAP_GRID ); n[PZ] = grid * round( n[PZ]/grid );
} }
// QUERIES // QUERIES

View file

@ -929,36 +929,21 @@ TGPolygon remove_dups( const TGPolygon &poly ) {
} }
#endif #endif
static inline double
snap (double value, double grid_size)
{
// I have no idea if this really works.
double factor = 1.0 / grid_size;
return double(int(value * factor)) / factor;
}
static inline Point3D
snap (const Point3D &p, double grid_size)
{
Point3D result;
result.setx(snap(p.x(), grid_size));
result.sety(snap(p.y(), grid_size));
result.setz(snap(p.z(), grid_size));
//cout << result << endl;
return result;
}
// snap all points in a polygon to the given grid size. // snap all points in a polygon to the given grid size.
TGPolygon snap (const TGPolygon &poly, double grid_size) TGPolygon snap (const TGPolygon &poly, double grid_size)
{ {
TGPolygon result; TGPolygon result;
for (int contour = 0; contour < poly.contours(); contour++) { Point3D pt;
for (int i = 0; i < poly.contour_size(contour); i++) { for (int contour = 0; contour < poly.contours(); contour++) {
result.add_node(contour, snap(poly.get_pt(contour, i), grid_size)); for (int i = 0; i < poly.contour_size(contour); i++) {
pt = poly.get_pt(contour, i);
pt.snap( grid_size );
result.add_node(contour, pt);
}
result.set_hole_flag(contour, poly.get_hole_flag(contour));
} }
result.set_hole_flag(contour, poly.get_hole_flag(contour));
} return result;
return result;
} }

View file

@ -502,7 +502,6 @@ Point3D MakeTGPoint( IntPoint pt )
y = (double)( ((double)pt.Y) / (double)FIXEDPT ); y = (double)( ((double)pt.Y) / (double)FIXEDPT );
tg_pt = Point3D( x, y, -9999.0f); tg_pt = Point3D( x, y, -9999.0f);
tg_pt.snap();
return tg_pt; return tg_pt;
} }