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:
parent
effbefde41
commit
cbea4335f4
11 changed files with 64 additions and 52 deletions
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <Output/output.hxx>
|
||||
|
||||
#include "global.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 )
|
||||
{
|
||||
TGPolygon poly = rwy_polys[k].get_poly();
|
||||
poly = snap(poly, gSnap);
|
||||
rwy_polys[k].set_poly( poly );
|
||||
}
|
||||
|
||||
for ( unsigned int k = 0; k < pvmt_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = pvmt_polys[k].get_poly();
|
||||
poly = snap(poly, gSnap);
|
||||
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());
|
||||
|
||||
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);
|
||||
|
||||
// Finally find slivers in base
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <Polygon/chop.hxx>
|
||||
#include <Geometry/poly_support.hxx>
|
||||
|
||||
#include "global.hxx"
|
||||
#include "beznode.hxx"
|
||||
#include "closedpoly.hxx"
|
||||
|
||||
|
@ -277,7 +278,6 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
|
|||
// add the pavement vertex
|
||||
// convert from lat/lon to geo
|
||||
// (maybe later) - check some simgear objects...
|
||||
curLoc.snap();
|
||||
dst->push_back( curLoc );
|
||||
|
||||
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) );
|
||||
|
||||
// add the feature vertex
|
||||
curLoc.snap();
|
||||
dst->push_back( curLoc );
|
||||
|
||||
if (p==0)
|
||||
|
@ -324,7 +323,6 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
|
|||
nextLoc = nextNode->GetLoc();
|
||||
|
||||
// just add the one vertex - dist is small
|
||||
curLoc.snap();
|
||||
dst->push_back( curLoc );
|
||||
|
||||
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 );
|
||||
pre_tess.add_contour( dst_contour, 1 );
|
||||
}
|
||||
|
||||
pre_tess = snap( pre_tess, gSnap );
|
||||
}
|
||||
|
||||
// save memory by deleting unneeded resources
|
||||
|
@ -441,10 +441,10 @@ int ClosedPoly::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams,
|
|||
TGTexParams tp;
|
||||
|
||||
TGPolygon clipped = tgPolygonDiffClipper( pre_tess, *accum );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours());
|
||||
|
||||
tgPolygonFindSlivers( clipped, slivers );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours());
|
||||
|
||||
sp.erase();
|
||||
sp.set_poly( clipped );
|
||||
sp.set_material( material );
|
||||
|
@ -453,6 +453,7 @@ int ClosedPoly::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams,
|
|||
rwy_polys->push_back( sp );
|
||||
|
||||
*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 (ds_id) {
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
|
||||
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)
|
||||
const double coarse_grid = 300.0;
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
|
||||
#include <Geometry/poly_support.hxx>
|
||||
|
||||
#include "global.hxx"
|
||||
#include "apt_math.hxx"
|
||||
#include "helipad.hxx"
|
||||
|
@ -61,12 +63,18 @@ void Helipad::gen_helipad( const TGPolygon& runway,
|
|||
Point3D a2 = runway.get_pt(0, 0);
|
||||
Point3D a3 = runway.get_pt(0, 3);
|
||||
|
||||
#if 0
|
||||
if ( startl_pct > 0.0 ) {
|
||||
startl_pct -= nudge * SG_EPSILON;
|
||||
}
|
||||
if ( endl_pct < 1.0 ) {
|
||||
endl_pct += nudge * SG_EPSILON;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( startl_pct < 0.0 ) {
|
||||
startl_pct = 0.0;
|
||||
}
|
||||
|
||||
if ( 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
|
||||
// for that by nudging the areas a bit bigger so we don't end up
|
||||
// with polygon slivers.
|
||||
#if 0
|
||||
if ( startw_pct > 0.0 || endw_pct < 1.0 ) {
|
||||
if ( startw_pct > 0.0 ) {
|
||||
startw_pct -= nudge * SG_EPSILON;
|
||||
|
@ -85,6 +94,7 @@ void Helipad::gen_helipad( const TGPolygon& runway,
|
|||
endw_pct += nudge * SG_EPSILON;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "start len % = " << startl_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, p1 );
|
||||
section.add_node( 0, p3 );
|
||||
section = snap( section, gSnap );
|
||||
|
||||
// print runway points
|
||||
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.
|
||||
#if 0
|
||||
TGPolygon clipped = tgPolygonDiff( section, *accum );
|
||||
#else
|
||||
TGPolygon clipped = tgPolygonDiffClipper( section, *accum );
|
||||
#endif
|
||||
|
||||
tgPolygonFindSlivers( clipped, slivers );
|
||||
|
||||
// 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 );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "section = " << clipped.contours());
|
||||
|
||||
#if 0
|
||||
*accum = tgPolygonUnion( section, *accum );
|
||||
#else
|
||||
*accum = tgPolygonUnionClipper( section, *accum );
|
||||
#endif
|
||||
|
||||
// Store away what we need to know for texture coordinate
|
||||
// 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;
|
||||
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
|
||||
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
|
||||
*apt_clearing = tgPolygonUnionClipper(safe_base, *apt_clearing);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
// for debugging clipping errors
|
||||
#include <Polygon/chop.hxx>
|
||||
|
||||
#include "global.hxx"
|
||||
#include "beznode.hxx"
|
||||
#include "linearfeature.hxx"
|
||||
#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_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) )
|
||||
{
|
||||
|
@ -756,6 +755,7 @@ int LinearFeature::Finish( bool closed, unsigned int idx )
|
|||
poly.add_node( 0, prev_outer );
|
||||
poly.add_node( 0, cur_outer );
|
||||
poly.add_node( 0, cur_inner );
|
||||
poly = snap( poly, gSnap );
|
||||
|
||||
#if DEBUG_LF
|
||||
char feature_name[128];
|
||||
|
|
|
@ -112,8 +112,9 @@ static void help( int argc, char **argv, const string_list& elev_src ) {
|
|||
}
|
||||
|
||||
// TODO: where do these belong
|
||||
int nudge = 10;
|
||||
int nudge = 0;
|
||||
double slope_max = 0.2;
|
||||
double gSnap = 0.0000001;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
@ -173,6 +174,10 @@ int main(int argc, char **argv)
|
|||
{
|
||||
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 )
|
||||
{
|
||||
last_apt_file = arg.substr(16);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <Geometry/poly_support.hxx>
|
||||
#include <Polygon/polygon.hxx>
|
||||
|
||||
#include "global.hxx"
|
||||
#include "apt_math.hxx"
|
||||
#include "beznode.hxx"
|
||||
#include "runway.hxx"
|
||||
|
@ -166,9 +167,11 @@ int Runway::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, supe
|
|||
|
||||
// generate area around runways
|
||||
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
|
||||
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
|
||||
*apt_clearing = tgPolygonUnionClipper( safe_base, *apt_clearing );
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
|
||||
#include <Geometry/poly_support.hxx>
|
||||
|
||||
#include "global.hxx"
|
||||
#include "beznode.hxx"
|
||||
#include "runway.hxx"
|
||||
|
@ -107,12 +109,18 @@ void Runway::gen_runway_section( const TGPolygon& runway,
|
|||
Point3D a2 = runway.get_pt(0, 0);
|
||||
Point3D a3 = runway.get_pt(0, 3);
|
||||
|
||||
#if 0
|
||||
if ( startl_pct > 0.0 ) {
|
||||
startl_pct -= nudge * SG_EPSILON;
|
||||
}
|
||||
if ( endl_pct < 1.0 ) {
|
||||
endl_pct += nudge * SG_EPSILON;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( startl_pct < 0.0 ) {
|
||||
startl_pct = 0.0;
|
||||
}
|
||||
|
||||
if ( 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
|
||||
// for that by nudging the areas a bit bigger so we don't end up
|
||||
// with polygon slivers.
|
||||
#if 0
|
||||
if ( startw_pct > 0.0 || endw_pct < 1.0 ) {
|
||||
if ( startw_pct > 0.0 ) {
|
||||
startw_pct -= nudge * SG_EPSILON;
|
||||
|
@ -131,6 +140,7 @@ void Runway::gen_runway_section( const TGPolygon& runway,
|
|||
endw_pct += nudge * SG_EPSILON;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "start len % = " << startl_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, p1 );
|
||||
section.add_node( 0, p3 );
|
||||
section = snap( section, gSnap );
|
||||
|
||||
// print runway points
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "pre clipped runway pts " << material_prefix << material);
|
||||
|
|
|
@ -50,9 +50,6 @@
|
|||
//const double fgPoint3_Epsilon = 0.0000001;
|
||||
const double fgPoint3_Epsilon = 0.000001;
|
||||
|
||||
#define DO_SNAP 0
|
||||
#define SNAP_GRID (0.0000001)
|
||||
|
||||
enum {PX, PY, PZ}; // axes
|
||||
|
||||
// Kludge for msvc++ 6.0 - requires forward decls of friend functions.
|
||||
|
@ -104,7 +101,7 @@ public:
|
|||
void setradius(const double z);
|
||||
void setelev(const double z);
|
||||
|
||||
void snap(void);
|
||||
void snap( double grid );
|
||||
|
||||
// Queries
|
||||
|
||||
|
@ -339,11 +336,11 @@ inline void Point3D::setelev(const double 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[PY] = SNAP_GRID * round( n[PY]/SNAP_GRID );
|
||||
n[PZ] = SNAP_GRID * round( n[PZ]/SNAP_GRID );
|
||||
n[PX] = grid * round( n[PX]/grid );
|
||||
n[PY] = grid * round( n[PY]/grid );
|
||||
n[PZ] = grid * round( n[PZ]/grid );
|
||||
}
|
||||
|
||||
// QUERIES
|
||||
|
|
|
@ -929,35 +929,20 @@ TGPolygon remove_dups( const TGPolygon &poly ) {
|
|||
}
|
||||
#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.
|
||||
TGPolygon snap (const TGPolygon &poly, double grid_size)
|
||||
{
|
||||
TGPolygon result;
|
||||
Point3D pt;
|
||||
for (int contour = 0; contour < poly.contours(); contour++) {
|
||||
for (int i = 0; i < poly.contour_size(contour); i++) {
|
||||
result.add_node(contour, snap(poly.get_pt(contour, i), grid_size));
|
||||
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));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -502,7 +502,6 @@ Point3D MakeTGPoint( IntPoint pt )
|
|||
y = (double)( ((double)pt.Y) / (double)FIXEDPT );
|
||||
|
||||
tg_pt = Point3D( x, y, -9999.0f);
|
||||
tg_pt.snap();
|
||||
|
||||
return tg_pt;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue