1
0
Fork 0

ran uncrustify on Polygon Library files. Makes it much more readable.

ran a test with all tools (decode, genapts and construct) succesfuly.
This commit is contained in:
PSadrozinski 2011-12-16 22:51:29 -05:00 committed by Christian Schmitt
parent 9add3fdaae
commit f2af9db3c8
11 changed files with 1012 additions and 1351 deletions

View file

@ -47,10 +47,12 @@ using std::cout;
using std::endl;
static void clip_and_write_poly( string root, long int p_index,
const string &poly_type,
SGBucket b, const TGPolygon& shape,
bool preserve3d ) {
const string &poly_type,
SGBucket b, const TGPolygon& shape,
bool preserve3d )
{
Point3D c, min, max, p;
c = Point3D( b.get_center_lon(), b.get_center_lat(), 0 );
double span = b.get_width();
TGPolygon base, result;
@ -58,24 +60,23 @@ static void clip_and_write_poly( string root, long int p_index,
// calculate bucket dimensions
if ( (c.y() >= -89.0) && (c.y() < 89.0) ) {
min.setx( c.x() - span / 2.0 );
max.setx( c.x() + span / 2.0 );
min.sety( c.y() - SG_HALF_BUCKET_SPAN );
max.sety( c.y() + SG_HALF_BUCKET_SPAN );
min.setx( c.x() - span / 2.0 );
max.setx( c.x() + span / 2.0 );
min.sety( c.y() - SG_HALF_BUCKET_SPAN );
max.sety( c.y() + SG_HALF_BUCKET_SPAN );
} else if ( c.y() < -89.0) {
min.setx( -90.0 );
max.setx( -89.0 );
min.sety( -180.0 );
max.sety( 180.0 );
min.setx( -90.0 );
max.setx( -89.0 );
min.sety( -180.0 );
max.sety( 180.0 );
} else if ( c.y() >= 89.0) {
min.setx( 89.0 );
max.setx( 90.0 );
min.sety( -180.0 );
max.sety( 180.0 );
} else {
SG_LOG ( SG_GENERAL, SG_ALERT,
"Out of range latitude in clip_and_write_poly() = " << c.y() );
}
min.setx( 89.0 );
max.setx( 90.0 );
min.sety( -180.0 );
max.sety( 180.0 );
} else
SG_LOG( SG_GENERAL, SG_ALERT,
"Out of range latitude in clip_and_write_poly() = " << c.y() );
min.setz( 0.0 );
max.setz( 0.0 );
@ -91,70 +92,68 @@ static void clip_and_write_poly( string root, long int p_index,
// SG_LOG( SG_GENERAL, SG_DEBUG, "base = 4 vertices" );
/*
FILE *bfp= fopen("base", "w");
gpc_write_polygon(bfp, &base);
fclose(bfp);
*/
FILE *bfp= fopen("base", "w");
gpc_write_polygon(bfp, &base);
fclose(bfp);
*/
SG_LOG(SG_GENERAL, SG_DEBUG, "shape contours = " << shape.contours() );
for ( int ii = 0; ii < shape.contours(); ii++ ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " hole = " << shape.get_hole_flag(ii) );
}
cout << "shape contours = " << shape.contours() << " ";
for ( int ii = 0; ii < shape.contours(); ii++ )
cout << "hole = " << shape.get_hole_flag(ii) << " ";
cout << endl;
result = tgPolygonInt( base, shape );
// write_polygon(shape, "shape");
// write_polygon(result, "result");
SG_LOG(SG_GENERAL, SG_DEBUG, "result contours = " << result.contours() );
cout << "result contours = " << result.contours() << " ";
for ( int ii = 0; ii < result.contours(); ii++ ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " hole = " << result.get_hole_flag(ii) );
cout << "hole = " << result.get_hole_flag(ii) << " ";
//if ( result.get_hole_flag(ii) ) {
// exit(0);
//}
}
if ( preserve3d ) {
cout << endl;
if ( preserve3d )
result.inherit_elevations( shape );
}
if ( result.contours() > 0 ) {
long int t_index = b.gen_index();
string path = root + "/" + b.gen_base_path();
long int t_index = b.gen_index();
string path = root + "/" + b.gen_base_path();
SGPath sgp( path );
sgp.append( "dummy" );
sgp.create_dir( 0755 );
sprintf( tile_name, "%ld", t_index );
string polyfile = path + "/" + tile_name;
sprintf( tile_name, "%ld", t_index );
string polyfile = path + "/" + tile_name;
sprintf( poly_index, "%ld", p_index );
polyfile += ".";
polyfile += poly_index;
sprintf( poly_index, "%ld", p_index );
polyfile += ".";
polyfile += poly_index;
FILE *rfp= fopen( polyfile.c_str(), "w" );
if ( preserve3d ) {
FILE *rfp = fopen( polyfile.c_str(), "w" );
if ( preserve3d )
fprintf( rfp, "#3D\n" );
} else {
else
fprintf( rfp, "#2D\n" );
}
fprintf( rfp, "%s\n", poly_type.c_str() );
fprintf( rfp, "%s\n", poly_type.c_str() );
fprintf( rfp, "%d\n", result.contours() );
for ( int i = 0; i < result.contours(); ++i ) {
fprintf( rfp, "%d\n", result.contour_size(i) );
fprintf( rfp, "%d\n", result.get_hole_flag(i) );
for ( int j = 0; j < result.contour_size(i); ++j ) {
p = result.get_pt( i, j );
if ( preserve3d ) {
fprintf( rfp, "%d\n", result.contours() );
for ( int i = 0; i < result.contours(); ++i ) {
fprintf( rfp, "%d\n", result.contour_size(i) );
fprintf( rfp, "%d\n", result.get_hole_flag(i) );
for ( int j = 0; j < result.contour_size(i); ++j ) {
p = result.get_pt( i, j );
if ( preserve3d )
fprintf( rfp, "%.15f %.15f %.15f\n", p.x(), p.y(), p.z() );
} else {
else
fprintf( rfp, "%.15f %.15f\n", p.x(), p.y() );
}
}
}
fclose( rfp );
}
}
fclose( rfp );
}
}
@ -169,23 +168,19 @@ void tgChopNormalPolygon( const string& path, const string& poly_type,
int i, j;
// bail out immediately if polygon is empty
if ( shape.contours() == 0 ) {
return;
}
if ( shape.contours() == 0 )
return;
min = Point3D( 200.0 );
max = Point3D( -200.0 );
// find min/max of polygon
for ( i = 0; i < shape.contours(); i++ ) {
for ( j = 0; j < shape.contour_size(i); j++ ) {
p = shape.get_pt( i, j );
for ( j = 0; j < shape.contour_size(i); j++ ) {
p = shape.get_pt( i, j );
if ( p.x() < min.x() ) { min.setx( p.x() ); }
if ( p.y() < min.y() ) { min.sety( p.y() ); }
if ( p.x() > max.x() ) { max.setx( p.x() ); }
if ( p.y() > max.y() ) { max.sety( p.y() ); }
}
if ( p.x() < min.x() ) min.setx( p.x() ); if ( p.y() < min.y() ) min.sety( p.y() ); if ( p.x() > max.x() ) max.setx( p.x() ); if ( p.y() > max.y() ) max.sety( p.y() );
}
}
// get next polygon index
@ -202,27 +197,27 @@ void tgChopNormalPolygon( const string& path, const string& poly_type,
SG_LOG( SG_GENERAL, SG_DEBUG, " Bucket max = " << b_max );
if ( b_min == b_max ) {
// shape entirely contained in a single bucket, write and bail
clip_and_write_poly( path, index, poly_type, b_min, shape, preserve3d );
return;
// shape entirely contained in a single bucket, write and bail
clip_and_write_poly( path, index, poly_type, b_min, shape, preserve3d );
return;
}
SGBucket b_cur;
int dx, dy;
sgBucketDiff(b_min, b_max, &dx, &dy);
SG_LOG( SG_GENERAL, SG_INFO,
" polygon spans tile boundaries" );
SG_LOG( SG_GENERAL, SG_DEBUG, " dx = " << dx
<< " dy = " << dy );
SG_LOG( SG_GENERAL, SG_INFO,
" polygon spans tile boundaries" );
SG_LOG( SG_GENERAL, SG_DEBUG, " dx = " << dx
<< " dy = " << dy );
if ( (dx > 2880) || (dy > 1440) )
throw sg_exception("something is really wrong in split_polygon()!!!!");
if ( dy <= 1 ) {
// we are down to at most two rows, write each column and then bail
double min_center_lat=b_min.get_center_lat();
double min_center_lon=b_min.get_center_lon();
// we are down to at most two rows, write each column and then bail
double min_center_lat = b_min.get_center_lat();
double min_center_lon = b_min.get_center_lon();
for ( j = 0; j <= dy; ++j ) {
for ( i = 0; i <= dx; ++i ) {
b_cur = sgBucketOffset(min_center_lon, min_center_lat, i, j);
@ -230,7 +225,7 @@ void tgChopNormalPolygon( const string& path, const string& poly_type,
preserve3d );
}
}
return;
return;
}
// we have two or more rows left, split in half (along a
@ -243,31 +238,30 @@ void tgChopNormalPolygon( const string& path, const string& poly_type,
SGBucket b_clip = sgBucketOffset(min.x(), min.y(), 0, mid);
double clip_line = b_clip.get_center_lat();
if ( (clip_line >= -90.0 + SG_HALF_BUCKET_SPAN)
&& (clip_line < 90.0 - SG_HALF_BUCKET_SPAN) )
{
clip_line += SG_HALF_BUCKET_SPAN;
} else if ( clip_line < -89.0 ) {
clip_line = -89.0;
} else if ( clip_line >= 89.0 ) {
clip_line = 90.0;
} else {
SG_LOG ( SG_GENERAL, SG_ALERT,
"Out of range latitude in clip_and_write_poly() = "
<< clip_line );
&& (clip_line < 90.0 - SG_HALF_BUCKET_SPAN) )
clip_line += SG_HALF_BUCKET_SPAN;
else if ( clip_line < -89.0 )
clip_line = -89.0;
else if ( clip_line >= 89.0 )
clip_line = 90.0;
else {
SG_LOG( SG_GENERAL, SG_ALERT,
"Out of range latitude in clip_and_write_poly() = "
<< clip_line );
}
{
//
// Crop bottom area (hopefully by putting this in it's own
// scope we can shorten the life of some really large data
// structures to reduce memory use)
//
//
// Crop bottom area (hopefully by putting this in it's own
// scope we can shorten the life of some really large data
// structures to reduce memory use)
//
SG_LOG ( SG_GENERAL, SG_DEBUG,
"Generating bottom half (" << min.y() << "-" <<
clip_line << ")" );
SG_LOG( SG_GENERAL, SG_DEBUG,
"Generating bottom half (" << min.y() << "-" <<
clip_line << ")" );
TGPolygon bottom, bottom_clip;
TGPolygon bottom, bottom_clip;
bottom.erase();
bottom_clip.erase();
@ -279,21 +273,21 @@ void tgChopNormalPolygon( const string& path, const string& poly_type,
bottom_clip = tgPolygonInt( bottom, shape );
tgChopNormalPolygon( path, poly_type, bottom_clip, preserve3d );
tgChopNormalPolygon( path, poly_type, bottom_clip, preserve3d );
}
{
//
// Crop top area (hopefully by putting this in it's own scope
// we can shorten the life of some really large data
// structures to reduce memory use)
//
//
// Crop top area (hopefully by putting this in it's own scope
// we can shorten the life of some really large data
// structures to reduce memory use)
//
SG_LOG ( SG_GENERAL, SG_DEBUG,
"Generating top half (" << clip_line << "-" <<
max.y() << ")" );
SG_LOG( SG_GENERAL, SG_DEBUG,
"Generating top half (" << clip_line << "-" <<
max.y() << ")" );
TGPolygon top, top_clip;
TGPolygon top, top_clip;
top.erase();
top_clip.erase();
@ -305,7 +299,7 @@ void tgChopNormalPolygon( const string& path, const string& poly_type,
top_clip = tgPolygonInt( top, shape );
tgChopNormalPolygon( path, poly_type, top_clip, preserve3d );
tgChopNormalPolygon( path, poly_type, top_clip, preserve3d );
}
}
@ -322,23 +316,19 @@ void tgChopBigSimplePolygon( const string& path, const string& poly_type,
int i, j;
// bail out immediately if polygon is empty
if ( shape.contours() == 0 ) {
return;
}
if ( shape.contours() == 0 )
return;
min = Point3D( 200.0 );
max = Point3D( -200.0 );
// find min/max of polygon
for ( i = 0; i < shape.contours(); i++ ) {
for ( j = 0; j < shape.contour_size(i); j++ ) {
p = shape.get_pt( i, j );
for ( j = 0; j < shape.contour_size(i); j++ ) {
p = shape.get_pt( i, j );
if ( p.x() < min.x() ) { min.setx( p.x() ); }
if ( p.y() < min.y() ) { min.sety( p.y() ); }
if ( p.x() > max.x() ) { max.setx( p.x() ); }
if ( p.y() > max.y() ) { max.sety( p.y() ); }
}
if ( p.x() < min.x() ) min.setx( p.x() ); if ( p.y() < min.y() ) min.sety( p.y() ); if ( p.x() > max.x() ) max.setx( p.x() ); if ( p.y() > max.y() ) max.sety( p.y() );
}
}
// get next polygon index
@ -355,36 +345,36 @@ void tgChopBigSimplePolygon( const string& path, const string& poly_type,
SG_LOG( SG_GENERAL, SG_DEBUG, " Bucket max = " << b_max );
if ( b_min == b_max ) {
// shape entirely contained in a single bucket, write and bail
clip_and_write_poly( path, index, poly_type, b_min, shape, preserve3d );
return;
// shape entirely contained in a single bucket, write and bail
clip_and_write_poly( path, index, poly_type, b_min, shape, preserve3d );
return;
}
SGBucket b_cur;
int dx, dy;
sgBucketDiff(b_min, b_max, &dx, &dy);
SG_LOG( SG_GENERAL, SG_INFO,
" polygon spans tile boundaries" );
SG_LOG( SG_GENERAL, SG_DEBUG, " dx = " << dx
<< " dy = " << dy );
SG_LOG( SG_GENERAL, SG_INFO,
" polygon spans tile boundaries" );
SG_LOG( SG_GENERAL, SG_DEBUG, " dx = " << dx
<< " dy = " << dy );
if ( (dx > 2880) || (dy > 1440) )
throw sg_exception("something is really wrong in split_polygon()!!!!");
if ( dy <= 1 ) {
// we are down to at most two rows, write each column and then
// bail
// we are down to at most two rows, write each column and then
// bail
double min_center_lat = b_min.get_center_lat();
double min_center_lon = b_min.get_center_lon();
for ( j = 0; j <= 1; ++j ) {
for ( i = 0; i <= dx; ++i ) {
b_cur = sgBucketOffset(min_center_lon, min_center_lat, i, j);
clip_and_write_poly( path, index, poly_type, b_cur, shape,
for ( j = 0; j <= 1; ++j ) {
for ( i = 0; i <= dx; ++i ) {
b_cur = sgBucketOffset(min_center_lon, min_center_lat, i, j);
clip_and_write_poly( path, index, poly_type, b_cur, shape,
preserve3d );
}
}
return;
}
}
return;
}
// we have more than one row left, split in half and recurse with
@ -396,73 +386,71 @@ void tgChopBigSimplePolygon( const string& path, const string& poly_type,
// determine horizontal clip line
SGBucket b_clip = sgBucketOffset(min.x(), min.y(), 0, mid);
double clip_line = b_clip.get_center_lat();
if ( (clip_line >= -89.0) && (clip_line < 89.0) ) {
clip_line += SG_HALF_BUCKET_SPAN;
} else if ( clip_line < -89.0 ) {
clip_line = -89.0;
} else if ( clip_line >= 89.0 ) {
clip_line = 90.0;
} else {
SG_LOG ( SG_GENERAL, SG_ALERT,
"Out of range latitude in clip_and_write_poly() = "
<< clip_line );
if ( (clip_line >= -89.0) && (clip_line < 89.0) )
clip_line += SG_HALF_BUCKET_SPAN;
else if ( clip_line < -89.0 )
clip_line = -89.0;
else if ( clip_line >= 89.0 )
clip_line = 90.0;
else {
SG_LOG( SG_GENERAL, SG_ALERT,
"Out of range latitude in clip_and_write_poly() = "
<< clip_line );
}
{
//
// Crop bottom area (hopefully by putting this in it's own
// scope we can shorten the life of some really large data
// structures to reduce memory use)
//
//
// Crop bottom area (hopefully by putting this in it's own
// scope we can shorten the life of some really large data
// structures to reduce memory use)
//
SG_LOG ( SG_GENERAL, SG_DEBUG,
"Generating bottom half (" << min.y() << "-" <<
clip_line << ")" );
SG_LOG( SG_GENERAL, SG_DEBUG,
"Generating bottom half (" << min.y() << "-" <<
clip_line << ")" );
TGPolygon bottom, bottom_clip;
if ( shape.total_size() < 50000 ) {
bottom.erase();
bottom_clip.erase();
TGPolygon bottom, bottom_clip;
if ( shape.total_size() < 50000 ) {
bottom.erase();
bottom_clip.erase();
bottom.add_node( 0, Point3D(-180.0, min.y(), 0) );
bottom.add_node( 0, Point3D(180.0, min.y(), 0) );
bottom.add_node( 0, Point3D(180.0, clip_line, 0) );
bottom.add_node( 0, Point3D(-180.0, clip_line, 0) );
bottom.add_node( 0, Point3D(-180.0, min.y(), 0) );
bottom.add_node( 0, Point3D(180.0, min.y(), 0) );
bottom.add_node( 0, Point3D(180.0, clip_line, 0) );
bottom.add_node( 0, Point3D(-180.0, clip_line, 0) );
bottom_clip = tgPolygonInt( bottom, shape );
} else {
bottom_clip = horizontal_clip( shape, clip_line, Below );
}
bottom_clip = tgPolygonInt( bottom, shape );
} else
bottom_clip = horizontal_clip( shape, clip_line, Below );
tgChopBigSimplePolygon( path, poly_type, bottom_clip, preserve3d );
tgChopBigSimplePolygon( path, poly_type, bottom_clip, preserve3d );
}
{
//
// Crop top area (hopefully by putting this in it's own scope
// we can shorten the life of some really large data
// structures to reduce memory use)
//
//
// Crop top area (hopefully by putting this in it's own scope
// we can shorten the life of some really large data
// structures to reduce memory use)
//
SG_LOG ( SG_GENERAL, SG_DEBUG,
"Generating top half (" << clip_line << "-" <<
max.y() << ")" );
SG_LOG( SG_GENERAL, SG_DEBUG,
"Generating top half (" << clip_line << "-" <<
max.y() << ")" );
TGPolygon top, top_clip;
if ( shape.total_size() < 50000 ) {
top.erase();
top_clip.erase();
TGPolygon top, top_clip;
if ( shape.total_size() < 50000 ) {
top.erase();
top_clip.erase();
top.add_node( 0, Point3D(-180.0, clip_line, 0) );
top.add_node( 0, Point3D(180.0, clip_line, 0) );
top.add_node( 0, Point3D(180.0, max.y(), 0) );
top.add_node( 0, Point3D(-180.0, max.y(), 0) );
top.add_node( 0, Point3D(-180.0, clip_line, 0) );
top.add_node( 0, Point3D(180.0, clip_line, 0) );
top.add_node( 0, Point3D(180.0, max.y(), 0) );
top.add_node( 0, Point3D(-180.0, max.y(), 0) );
top_clip = tgPolygonInt( top, shape );
} else {
top_clip = horizontal_clip( shape, clip_line, Above );
}
top_clip = tgPolygonInt( top, shape );
} else
top_clip = horizontal_clip( shape, clip_line, Above );
tgChopBigSimplePolygon( path, poly_type, top_clip, preserve3d );
tgChopBigSimplePolygon( path, poly_type, top_clip, preserve3d );
}
}

View file

@ -19,7 +19,7 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: index.cxx,v 1.7 2004-11-19 22:25:50 curt Exp $
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
@ -35,15 +35,16 @@ static long int poly_index;
static string poly_path;
// initialize the unique polygon index counter stored in path
bool poly_index_init( string path ) {
bool poly_index_init( string path )
{
poly_path = path;
FILE *fp = fopen( poly_path.c_str(), "r" );
if ( fp == NULL ) {
SG_LOG(SG_GENERAL, SG_WARN, "Warning: cannot open " << poly_path);
poly_index = 0;
return false;
SG_LOG(SG_GENERAL, SG_WARN, "Warning: cannot open " << poly_path);
poly_index = 0;
return false;
}
fscanf( fp, "%ld", &poly_index );
@ -55,15 +56,15 @@ bool poly_index_init( string path ) {
// increment the persistant counter and return the next poly_index
long int poly_index_next() {
long int poly_index_next()
{
++poly_index;
FILE *fp = fopen( poly_path.c_str(), "w" );
if ( fp == NULL ) {
SG_LOG(SG_GENERAL, SG_ALERT,
"Error cannot open " << poly_path << " for writing");
}
if ( fp == NULL )
SG_LOG(SG_GENERAL, SG_ALERT,
"Error cannot open " << poly_path << " for writing");
fprintf( fp, "%ld\n", poly_index );

View file

@ -19,7 +19,7 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: names.hxx,v 1.16 2007-10-31 15:05:13 curt Exp $
#ifndef _NAMES_HXX
#define _NAMES_HXX
@ -31,17 +31,17 @@
inline static bool is_ocean_area( const std::string &area )
{
return area=="Ocean" || area=="Bay Estuary or Ocean";
return area == "Ocean" || area == "Bay Estuary or Ocean";
}
inline static bool is_void_area( const std::string &area )
{
return area=="Void Area";
return area == "Void Area";
}
inline static bool is_null_area( const std::string& area )
{
return area=="Null";
return area == "Null";
}
#endif // _NAMES_HXX

View file

@ -8,16 +8,16 @@
class point2d {
public:
union {
double x;
double dist;
double lon;
};
union {
double y;
double theta;
double lat;
};
union {
double x;
double dist;
double lon;
};
union {
double y;
double theta;
double lat;
};
};
#endif // TG_POINT2D_HXX

File diff suppressed because it is too large Load diff

View file

@ -25,9 +25,9 @@
#define _POLYGON_HXX
#ifndef __cplusplus
#ifndef __cplusplus
# error This library requires C++
#endif
#endif
/* which clipping lib to use? Looks like we should go with clipper
* It appears to be both faster and generates better accuracy
@ -86,136 +86,155 @@ class TGPolygon {
private:
polytype poly; // polygons
point_list inside_list; // point inside list
int_list hole_list; // hole flag list
polytype poly; // polygons
point_list inside_list; // point inside list
int_list hole_list; // hole flag list
public:
// Constructor and destructor
TGPolygon( void );
~TGPolygon( void );
// Constructor and destructor
TGPolygon( void );
~TGPolygon( void );
// Add a contour
inline void add_contour( const point_list contour, const int hole_flag ) {
poly.push_back( contour );
inside_list.push_back( Point3D( 0.0 ) );
hole_list.push_back( hole_flag );
// Add a contour
inline void add_contour( const point_list contour, const int hole_flag )
{
poly.push_back( contour );
inside_list.push_back( Point3D( 0.0 ) );
hole_list.push_back( hole_flag );
}
// Get a contour
inline point_list get_contour( const int i ) const
{
return poly[i];
}
// Delete a contour
inline void delete_contour( const int i )
{
polytype_iterator start_poly = poly.begin();
poly.erase( start_poly + i );
point_list_iterator start_inside = inside_list.begin();
inside_list.erase( start_inside + i );
int_list_iterator start_hole = hole_list.begin();
hole_list.erase( start_hole + i );
}
// Add the specified node (index) to the polygon
inline void add_node( int contour, Point3D p )
{
if ( contour >= (int)poly.size() ) {
// extend polygon
point_list empty_contour;
empty_contour.clear();
for ( int i = 0; i < contour - (int)poly.size() + 1; ++i ) {
poly.push_back( empty_contour );
inside_list.push_back( Point3D(0.0) );
hole_list.push_back( 0 );
}
}
poly[contour].push_back( p );
}
// Get a contour
inline point_list get_contour( const int i ) const {
return poly[i];
}
// return size
inline int contours() const
{
return poly.size();
}
inline int contour_size( int contour ) const
{
return poly[contour].size();
}
inline int total_size() const
{
int size = 0;
// Delete a contour
inline void delete_contour( const int i ) {
polytype_iterator start_poly = poly.begin();
poly.erase( start_poly + i );
for ( int i = 0; i < contours(); ++i )
size += poly[i].size();
return size;
}
point_list_iterator start_inside = inside_list.begin();
inside_list.erase( start_inside + i );
// return the ith point from the specified contour
inline Point3D get_pt( int contour, int i ) const
{
return poly[contour][i];
}
int_list_iterator start_hole = hole_list.begin();
hole_list.erase( start_hole + i );
}
// update the value of a point
inline void set_pt( int contour, int i, const Point3D& p )
{
poly[contour][i] = p;
}
// Add the specified node (index) to the polygon
inline void add_node( int contour, Point3D p ) {
if ( contour >= (int)poly.size() ) {
// extend polygon
point_list empty_contour;
empty_contour.clear();
for ( int i = 0; i < contour - (int)poly.size() + 1; ++i ) {
poly.push_back( empty_contour );
inside_list.push_back( Point3D(0.0) );
hole_list.push_back( 0 );
}
}
poly[contour].push_back( p );
}
// get and set an arbitrary point inside the specified polygon contour
inline Point3D get_point_inside( const int contour ) const
{
return inside_list[contour];
}
inline void set_point_inside( int contour, const Point3D& p )
{
inside_list[contour] = p;
}
// return size
inline int contours() const { return poly.size(); }
inline int contour_size( int contour ) const {
return poly[contour].size();
}
inline int total_size() const {
int size = 0;
for ( int i = 0; i < contours(); ++i ) {
size += poly[i].size();
}
return size;
}
// get and set hole flag
inline int get_hole_flag( const int contour ) const
{
return hole_list[contour];
}
inline void set_hole_flag( const int contour, const int flag )
{
hole_list[contour] = flag;
}
inline bool has_holes() const
{
for (int i = 0; i < contours(); i++)
if (get_hole_flag(i))
return true;
return false;
}
// return the ith point from the specified contour
inline Point3D get_pt( int contour, int i ) const {
return poly[contour][i];
}
// Set the elevations of points in the current polgyon based on
// the elevations of points in source. For points that are not
// found in source, propogate the value from the nearest matching
// point.
void inherit_elevations( const TGPolygon &source );
// update the value of a point
inline void set_pt( int contour, int i, const Point3D& p ) {
poly[contour][i] = p;
}
// Set the elevations of all points to the specified values
void set_elevations( double elev );
// get and set an arbitrary point inside the specified polygon contour
inline Point3D get_point_inside( const int contour ) const {
return inside_list[contour];
}
inline void set_point_inside( int contour, const Point3D& p ) {
inside_list[contour] = p;
}
// shift every point in the polygon by lon, lat
void shift( double lon, double lat );
// get and set hole flag
inline int get_hole_flag( const int contour ) const {
return hole_list[contour];
}
inline void set_hole_flag( const int contour, const int flag ) {
hole_list[contour] = flag;
}
inline bool has_holes () const {
for (int i = 0; i < contours(); i++) {
if (get_hole_flag(i))
return true;
}
return false;
}
// erase
inline void erase()
{
poly.clear();
}
// Set the elevations of points in the current polgyon based on
// the elevations of points in source. For points that are not
// found in source, propogate the value from the nearest matching
// point.
void inherit_elevations( const TGPolygon &source );
// informational
// Set the elevations of all points to the specified values
void set_elevations( double elev );
// return the area of a contour (assumes simple polygons,
// i.e. non-self intersecting.)
//
// negative areas indicate counter clockwise winding
// positive areas indicate clockwise winding.
double area_contour( const int contour ) const;
// shift every point in the polygon by lon, lat
void shift( double lon, double lat );
// return the smallest interior angle of the contour
double minangle_contour( const int contour );
// erase
inline void erase() { poly.clear(); }
// return true if contour B is inside countour A
bool is_inside( int a, int b ) const;
// informational
// output
void write( const std::string& file ) const;
// return the area of a contour (assumes simple polygons,
// i.e. non-self intersecting.)
//
// negative areas indicate counter clockwise winding
// positive areas indicate clockwise winding.
double area_contour( const int contour ) const;
// return the smallest interior angle of the contour
double minangle_contour( const int contour );
// return true if contour B is inside countour A
bool is_inside( int a, int b ) const;
// output
void write( const std::string& file ) const;
// output
void write_contour( const int contour, const std::string& file ) const;
// output
void write_contour( const int contour, const std::string& file ) const;
};
@ -276,7 +295,7 @@ ClipPolyType tgPolygonUnion( const TGPolygon& subject, const ClipPolyType& clip
#endif
// Output
std::ostream &operator<< (std::ostream &output, const TGPolygon &poly);
std::ostream &operator<<(std::ostream &output, const TGPolygon &poly);
#endif // _POLYGON_HXX

View file

@ -37,43 +37,39 @@
// the x value of a point on the line that intersects with the
// horizontal line through y. Return true if an intersection is found,
// false otherwise.
static bool intersects_y( Point3D p0, Point3D p1, double y, Point3D *result ) {
static bool intersects_y( Point3D p0, Point3D p1, double y, Point3D *result )
{
// sort the end points
if ( p0.y() > p1.y() ) {
Point3D tmp = p0;
p0 = p1;
p1 = tmp;
}
if ( (y < p0.y()) || (y > p1.y()) ) {
// out of range of line segment, bail right away
return false;
Point3D tmp = p0;
p0 = p1;
p1 = tmp;
}
if ( (y < p0.y()) || (y > p1.y()) )
// out of range of line segment, bail right away
return false;
// equation of a line through (x0,y0) and (x1,y1):
//
//
// y = y1 + (x - x1) * (y0 - y1) / (x0 - x1)
// x = x1 + (y - y1) * (x0 - x1) / (y0 - y1)
double x;
if ( fabs(p0.y() - p1.y()) > CLIP_EPSILON ) {
x = p1.x() + (y - p1.y()) * (p0.x() - p1.x()) / (p0.y() - p1.y());
} else {
return false;
}
if ( fabs(p0.y() - p1.y()) > CLIP_EPSILON )
x = p1.x() + (y - p1.y()) * (p0.x() - p1.x()) / (p0.y() - p1.y());
else
return false;
result->setx(x);
result->sety(y);
if ( p0.x() <= p1.x() ) {
if ( (p0.x() <= x) && (x <= p1.x()) ) {
return true;
}
} else {
if ( (p0.x() >= x) && (x >= p1.x()) ) {
return true;
}
}
if ( (p0.x() <= x) && (x <= p1.x()) )
return true;
} else if ( (p0.x() >= x) && (x >= p1.x()) )
return true;
return false;
}
@ -81,24 +77,25 @@ static bool intersects_y( Point3D p0, Point3D p1, double y, Point3D *result ) {
// find the smallest point in contour 0 of poly such that x > min_x
// and y = y. Returns index of the found point, -1 if no match found.
static int find_point( const TGPolygon& poly, double min_x, double y ) {
static int find_point( const TGPolygon& poly, double min_x, double y )
{
Point3D p, save;
int index = -1;
save.setx( 361.0 );
for ( int i = 0; i < poly.contour_size( 0 ); ++i ) {
p = poly.get_pt( 0, i );
if ( p.y() == y ) {
// printf("(%d) p.y() = %.12f y = %.12f\n", i, p.y(), y);
// SG_LOG(SG_GENERAL, SG_DEBUG, " " << p);
if ( p.x() > min_x ) {
if ( p.x() < save.x() ) {
save = p;
index = i;
}
}
}
p = poly.get_pt( 0, i );
if ( p.y() == y ) {
// printf("(%d) p.y() = %.12f y = %.12f\n", i, p.y(), y);
// SG_LOG(SG_GENERAL, SG_DEBUG, " " << p);
if ( p.x() > min_x ) {
if ( p.x() < save.x() ) {
save = p;
index = i;
}
}
}
}
return index;
@ -108,31 +105,27 @@ static int find_point( const TGPolygon& poly, double min_x, double y ) {
// return if interesection is valid (not in the ignore list)
static bool valid_intersection( int intersection, const int_list& ignore_ints )
{
for ( int i = 0; i < (int)ignore_ints.size(); ++i ) {
if ( intersection == ignore_ints[i] ) {
return false;
}
}
for ( int i = 0; i < (int)ignore_ints.size(); ++i )
if ( intersection == ignore_ints[i] )
return false;
return true;
}
// return index of next valid intersection
static int next_intersection( const int_list& keep_ints,
const int_list& ignore_ints,
const int beginning_at )
static int next_intersection( const int_list& keep_ints,
const int_list& ignore_ints,
const int beginning_at )
{
// SG_LOG(SG_GENERAL, SG_DEBUG, "[ni] start_int = " << beginning_at);
int i = beginning_at;
if ( i < 0 ) { i = 0; }
while ( i < (int)keep_ints.size() ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, " i = " << i);
if ( keep_ints[i] != -1 ) {
if ( valid_intersection(keep_ints[i], ignore_ints) ) {
return i;
}
}
++i;
if ( i < 0 ) i = 0; while ( i < (int)keep_ints.size() ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, " i = " << i);
if ( keep_ints[i] != -1 )
if ( valid_intersection(keep_ints[i], ignore_ints) )
return i;
++i;
}
return -1;
@ -140,32 +133,28 @@ static int next_intersection( const int_list& keep_ints,
// return true if point.y() touches or is inside of line, else return false
inline bool is_on_or_inside( double line, Point3D p, fgSideType side ) {
inline bool is_on_or_inside( double line, Point3D p, fgSideType side )
{
if ( side == Above ) {
if ( p.y() >= line ) {
return true;
}
} else if ( side == Below ) {
if ( p.y() <= line ) {
return true;
}
}
if ( p.y() >= line )
return true;
} else if ( side == Below )
if ( p.y() <= line )
return true;
return false;
}
// return true if point.y() is inside of line, else return false
inline bool is_inside( double line, Point3D p, fgSideType side ) {
inline bool is_inside( double line, Point3D p, fgSideType side )
{
if ( side == Above ) {
if ( p.y() > line ) {
return true;
}
} else if ( side == Below ) {
if ( p.y() < line ) {
return true;
}
}
if ( p.y() > line )
return true;
} else if ( side == Below )
if ( p.y() < line )
return true;
return false;
}
@ -174,8 +163,8 @@ inline bool is_inside( double line, Point3D p, fgSideType side ) {
// Walk through the input polygon and split it into the
// portion that is inside the clip region
static bool simple_clip( const TGPolygon& in, const double y,
const fgSideType side,
TGPolygon& result )
const fgSideType side,
TGPolygon& result )
{
Point3D p, p_last, p_int;
int i;
@ -184,68 +173,65 @@ static bool simple_clip( const TGPolygon& in, const double y,
SG_LOG(SG_GENERAL, SG_DEBUG, "input poly size = " << in.total_size());
p_last = in.get_pt( 0, in.contour_size(0)-1 );
p_last = in.get_pt( 0, in.contour_size(0) - 1 );
for ( i = 0; i < (int)in.contour_size(0); ++i ) {
p = in.get_pt( 0, i );
p = in.get_pt( 0, i );
if ( (fabs(p.x() - p_last.x()) < CLIP_EPSILON) &&
(fabs(p.y() - p_last.y()) < CLIP_EPSILON) &&
(i > 0) ) {
// SG_LOG(SG_GENERAL, SG_WARN,
// "WARNING: p and p_last are identical at index = " << i);
}
if ( (fabs(p.x() - p_last.x()) < CLIP_EPSILON) &&
(fabs(p.y() - p_last.y()) < CLIP_EPSILON) &&
(i > 0) ) {
// SG_LOG(SG_GENERAL, SG_WARN,
// "WARNING: p and p_last are identical at index = " << i);
}
if ( is_on_or_inside(y, p, side) ) {
if ( is_on_or_inside(y, p_last, side) ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, "inside & inside " << i << " " << p);
result.add_node( 0, p );
} else {
if ( !intersects_y(p, p_last, y, &p_int) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "Huh, this should have intersected!");
return false;
} else {
// SG_LOG(SG_GENERAL, SG_DEBUG,
// "intersection outside to inside " << i << " "
// << p_int " i - 1 = " << in.get_pt( 0, i-1 ));
// SG_LOG(SG_GENERAL, SG_DEBUG, " i = " << in.get_pt( 0, i ));
// SG_LOG(SG_GENERAL, SG_DEBUG, " i + 1 = " << in.get_pt( 0, i+1 ));
result.add_node( 0, p_int );
if ( (fabs(p.x() - p_int.x()) < CLIP_EPSILON) &&
(fabs(p.y() - p_int.y()) < CLIP_EPSILON) )
{
// SG_LOG(SG_GENERAL, SG_DEBUG,
// "WARNING: p and p_int are identical, "
// << "omitting p");
} else {
SG_LOG(SG_GENERAL, SG_DEBUG, "adding intersection" << i << " " << p);
result.add_node( 0, p );
}
}
if ( is_on_or_inside(y, p, side) ) {
if ( is_on_or_inside(y, p_last, side) )
// SG_LOG(SG_GENERAL, SG_DEBUG, "inside & inside " << i << " " << p);
result.add_node( 0, p );
else {
if ( !intersects_y(p, p_last, y, &p_int) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "Huh, this should have intersected!");
return false;
} else {
// SG_LOG(SG_GENERAL, SG_DEBUG,
// "intersection outside to inside " << i << " "
// << p_int " i - 1 = " << in.get_pt( 0, i-1 ));
// SG_LOG(SG_GENERAL, SG_DEBUG, " i = " << in.get_pt( 0, i ));
// SG_LOG(SG_GENERAL, SG_DEBUG, " i + 1 = " << in.get_pt( 0, i+1 ));
result.add_node( 0, p_int );
if ( (fabs(p.x() - p_int.x()) < CLIP_EPSILON) &&
(fabs(p.y() - p_int.y()) < CLIP_EPSILON) ) {
// SG_LOG(SG_GENERAL, SG_DEBUG,
// "WARNING: p and p_int are identical, "
// << "omitting p");
} else {
SG_LOG(SG_GENERAL, SG_DEBUG, "adding intersection" << i << " " << p);
result.add_node( 0, p );
}
}
}
} else {
if ( is_inside(y, p_last, side) ) {
if ( !intersects_y(p, p_last, y, &p_int) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "Huh, this should have intersected!");
return false;
} else {
// SG_LOG(SG_GENERAL, SG_DEBUG,
// "intersection inside to outside " << i << " "
// << p_int);
if ( (fabs(p.x() - p_int.x()) < CLIP_EPSILON) &&
(fabs(p.y() - p_int.y()) < CLIP_EPSILON) )
{
SG_LOG(SG_GENERAL, SG_DEBUG,
"WARNING: p and p_int are identical, "
<< "omitting p");
} else {
result.add_node( 0, p_int );
}
}
}
}
} else {
if ( is_inside(y, p_last, side) ) {
if ( !intersects_y(p, p_last, y, &p_int) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "Huh, this should have intersected!");
return false;
} else {
// SG_LOG(SG_GENERAL, SG_DEBUG,
// "intersection inside to outside " << i << " "
// << p_int);
if ( (fabs(p.x() - p_int.x()) < CLIP_EPSILON) &&
(fabs(p.y() - p_int.y()) < CLIP_EPSILON) ) {
SG_LOG(SG_GENERAL, SG_DEBUG,
"WARNING: p and p_int are identical, "
<< "omitting p");
} else
result.add_node( 0, p_int );
}
}
}
p_last = p;
p_last = p;
}
return true;
@ -253,10 +239,10 @@ static bool simple_clip( const TGPolygon& in, const double y,
// build the list of intersections
static bool build_intersections( const TGPolygon& arcs, double line,
fgSideType side,
int_list& keep_ints,
int_list& ignore_ints )
static bool build_intersections( const TGPolygon& arcs, double line,
fgSideType side,
int_list& keep_ints,
int_list& ignore_ints )
{
keep_ints.clear();
ignore_ints.clear();
@ -265,63 +251,58 @@ static bool build_intersections( const TGPolygon& arcs, double line,
double current_x = -181.0;
while ( index >= 0 ) {
index = find_point( arcs, current_x, line );
if ( index >= 0 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "intersection at " << index << " = "
<< arcs.get_pt( 0, index ));
keep_ints.push_back( index );
current_x = arcs.get_pt( 0, index ).x();
index = find_point( arcs, current_x, line );
if ( index >= 0 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "intersection at " << index << " = "
<< arcs.get_pt( 0, index ));
keep_ints.push_back( index );
current_x = arcs.get_pt( 0, index ).x();
int before = index - 1;
if ( before < 0 ) { before += arcs.contour_size(0); }
int after = (index + 1) % arcs.contour_size(0);
SG_LOG(SG_GENERAL, SG_DEBUG, " before = "
<< arcs.get_pt(0, before));
SG_LOG(SG_GENERAL, SG_DEBUG, " int = "
<< arcs.get_pt(0, index));
SG_LOG(SG_GENERAL, SG_DEBUG, " after = "
<< arcs.get_pt(0, after));
if ( side == Above ) {
if ( (arcs.get_pt(0, before).y() > line) &&
(arcs.get_pt(0, after).y() > line) )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "side = above");
SG_LOG(SG_GENERAL, SG_DEBUG,
"V intersection with clip line from above");
SG_LOG(SG_GENERAL, SG_DEBUG,
"Adding intersection to ignore_ints");
ignore_ints.push_back( index );
}
if ( (arcs.get_pt(0, before).y() <= line) &&
(arcs.get_pt(0, after).y() <= line) )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "side = above");
SG_LOG(SG_GENERAL, SG_DEBUG,
"V intersection with clip line from BELOW\n"
<< "or an extra in-clip-line intersection.\n"
<< "Adding intersection to ignore_ints");
ignore_ints.push_back( index );
}
} else if ( side == Below ) {
if ( (arcs.get_pt(0, before).y() >= line) &&
(arcs.get_pt(0, after).y() >= line) )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "side = below");
SG_LOG(SG_GENERAL, SG_DEBUG, "V intersection with clip line from above");
SG_LOG(SG_GENERAL, SG_DEBUG, "Adding intersection to ignore_ints");
ignore_ints.push_back( index );
}
if ( (arcs.get_pt(0, before).y() < line) &&
(arcs.get_pt(0, after).y() < line) )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "side = below");
SG_LOG(SG_GENERAL, SG_DEBUG, "V intersection with clip line from BELOW");
SG_LOG(SG_GENERAL, SG_DEBUG, "or an extra in-clip-line intersection.");
SG_LOG(SG_GENERAL, SG_DEBUG, "Adding intersection to ignore_ints");
ignore_ints.push_back( index );
}
}
}
int before = index - 1;
if ( before < 0 ) before += arcs.contour_size(0); int after = (index + 1) % arcs.contour_size(0);
SG_LOG(SG_GENERAL, SG_DEBUG, " before = "
<< arcs.get_pt(0, before));
SG_LOG(SG_GENERAL, SG_DEBUG, " int = "
<< arcs.get_pt(0, index));
SG_LOG(SG_GENERAL, SG_DEBUG, " after = "
<< arcs.get_pt(0, after));
if ( side == Above ) {
if ( (arcs.get_pt(0, before).y() > line) &&
(arcs.get_pt(0, after).y() > line) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "side = above");
SG_LOG(SG_GENERAL, SG_DEBUG,
"V intersection with clip line from above");
SG_LOG(SG_GENERAL, SG_DEBUG,
"Adding intersection to ignore_ints");
ignore_ints.push_back( index );
}
if ( (arcs.get_pt(0, before).y() <= line) &&
(arcs.get_pt(0, after).y() <= line) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "side = above");
SG_LOG(SG_GENERAL, SG_DEBUG,
"V intersection with clip line from BELOW\n"
<< "or an extra in-clip-line intersection.\n"
<< "Adding intersection to ignore_ints");
ignore_ints.push_back( index );
}
} else if ( side == Below ) {
if ( (arcs.get_pt(0, before).y() >= line) &&
(arcs.get_pt(0, after).y() >= line) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "side = below");
SG_LOG(SG_GENERAL, SG_DEBUG, "V intersection with clip line from above");
SG_LOG(SG_GENERAL, SG_DEBUG, "Adding intersection to ignore_ints");
ignore_ints.push_back( index );
}
if ( (arcs.get_pt(0, before).y() < line) &&
(arcs.get_pt(0, after).y() < line) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "side = below");
SG_LOG(SG_GENERAL, SG_DEBUG, "V intersection with clip line from BELOW");
SG_LOG(SG_GENERAL, SG_DEBUG, "or an extra in-clip-line intersection.");
SG_LOG(SG_GENERAL, SG_DEBUG, "Adding intersection to ignore_ints");
ignore_ints.push_back( index );
}
}
}
}
return true;
@ -329,7 +310,8 @@ static bool build_intersections( const TGPolygon& arcs, double line,
// test for duplicate nodes
TGPolygon fix_dups( TGPolygon& in ) {
TGPolygon fix_dups( TGPolygon& in )
{
TGPolygon result;
double x_last = -20000.0;
@ -337,15 +319,14 @@ TGPolygon fix_dups( TGPolygon& in ) {
double x, y;
for ( int i = 0; i < (int)in.contour_size(0); ++i ) {
x = in.get_pt(0, i).x();
y = in.get_pt(0, i).y();
if ( (x == x_last) && (y == y_last) ) {
// ignore
} else {
result.add_node(0, in.get_pt(0, i));
}
x_last = x;
y_last = y;
x = in.get_pt(0, i).x();
y = in.get_pt(0, i).y();
if ( (x == x_last) && (y == y_last) ) {
// ignore
} else
result.add_node(0, in.get_pt(0, i));
x_last = x;
y_last = y;
}
return result;
@ -357,9 +338,9 @@ TGPolygon fix_dups( TGPolygon& in ) {
// with single contour polygons (no holes.) Returns true if routine
// thinks it was successful.
static bool clip_contour( const TGPolygon& in, const double y,
const fgSideType side,
TGPolygon& result )
static bool clip_contour( const TGPolygon& in, const double y,
const fgSideType side,
TGPolygon& result )
{
TGPolygon result_arcs, arcs;
int i, i1, i2, index;
@ -367,13 +348,13 @@ static bool clip_contour( const TGPolygon& in, const double y,
// Step 1: sanity checks
if ( (int)in.contours() != 1 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "we only handle single contour polygons");
return false;
SG_LOG(SG_GENERAL, SG_DEBUG, "we only handle single contour polygons");
return false;
}
if ( (int)in.contour_size( 0 ) < 3 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "we must have at least three vertices to work");
return false;
SG_LOG(SG_GENERAL, SG_DEBUG, "we must have at least three vertices to work");
return false;
}
@ -381,15 +362,13 @@ static bool clip_contour( const TGPolygon& in, const double y,
// portion that is on or inside the clip line
if ( simple_clip( in, y, side, result_arcs ) ) {
if ( result_arcs.contours() > 0 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "result_arcs size = "
<< result_arcs.total_size());
} else {
SG_LOG(SG_GENERAL, SG_DEBUG, "empty result");
}
} else {
if ( result_arcs.contours() > 0 )
SG_LOG(SG_GENERAL, SG_DEBUG, "result_arcs size = "
<< result_arcs.total_size());
else
SG_LOG(SG_GENERAL, SG_DEBUG, "empty result");
} else
throw sg_exception("simple_clip_above() failed!");
}
// Step 3: check for trivial cases
@ -398,25 +377,25 @@ static bool clip_contour( const TGPolygon& in, const double y,
// trivial -- nothing inside of clip line
if ( result_arcs.contours() == 0 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "trivially empty");
return true;
SG_LOG(SG_GENERAL, SG_DEBUG, "trivially empty");
return true;
}
// trivial -- everything inside of clip line
i1 = find_point( result_arcs, -181.0, y );
if ( i1 < 0 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "trivially full");
result = result_arcs;
return true;
SG_LOG(SG_GENERAL, SG_DEBUG, "trivially full");
result = result_arcs;
return true;
}
// trivial -- single clip line intersection (polygon just nicks
// it) -- everything inside
i2 = find_point( result_arcs, result_arcs.get_pt(0,i1).x(), y );
i2 = find_point( result_arcs, result_arcs.get_pt(0, i1).x(), y );
if ( i2 < 0 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "trivially full (clip line nicks edge)");
result = result_arcs;
return true;
SG_LOG(SG_GENERAL, SG_DEBUG, "trivially full (clip line nicks edge)");
result = result_arcs;
return true;
}
@ -427,13 +406,12 @@ static bool clip_contour( const TGPolygon& in, const double y,
tmp.erase();
if ( side == Below ) {
for ( i = result_arcs.contour_size(0) - 1; i >= 0; --i ) {
Point3D p = result_arcs.get_pt( 0, i );
tmp.add_node( 0, p );
}
} else {
tmp = result_arcs;
}
for ( i = result_arcs.contour_size(0) - 1; i >= 0; --i ) {
Point3D p = result_arcs.get_pt( 0, i );
tmp.add_node( 0, p );
}
} else
tmp = result_arcs;
arcs = fix_dups( tmp );
@ -449,7 +427,7 @@ static bool clip_contour( const TGPolygon& in, const double y,
// individual contours.)
int start_int = next_intersection( keep_ints, ignore_ints, 0 );
int next_int = next_intersection( keep_ints, ignore_ints, start_int+1 );
int next_int = next_intersection( keep_ints, ignore_ints, start_int + 1 );
SG_LOG(SG_GENERAL, SG_DEBUG, "start_int = " << start_int);
SG_LOG(SG_GENERAL, SG_DEBUG, "next_int = " << next_int);
@ -457,72 +435,70 @@ static bool clip_contour( const TGPolygon& in, const double y,
// while we have keep_ints left to process
while ( start_int >= 0 ) {
point_list contour;
contour.clear();
point_list contour;
contour.clear();
index = keep_ints[next_int];
keep_ints[next_int] = -1;
SG_LOG(SG_GENERAL, SG_DEBUG, "\nstarting at point = "
<< arcs.get_pt(0,index));
index = keep_ints[next_int];
keep_ints[next_int] = -1;
SG_LOG(SG_GENERAL, SG_DEBUG, "\nstarting at point = "
<< arcs.get_pt(0, index));
while ( index != keep_ints[start_int] ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "index = " << index
<< " start_int = " << start_int
<< " keep_ints[start_int] = " << keep_ints[start_int]);
while ( index != keep_ints[start_int] ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "index = " << index
<< " start_int = " << start_int
<< " keep_ints[start_int] = " << keep_ints[start_int]);
// start with the 2nd item in the intersection list and
// traverse until we find another intersection
contour.push_back( arcs.get_pt(0,index) );
index = (index + 1) % arcs.contour_size(0);
while ( (arcs.get_pt(0,index).y() != y) ||
! valid_intersection(index, ignore_ints) )
{
contour.push_back( arcs.get_pt(0,index) );
index = (index + 1) % arcs.contour_size(0);
}
contour.push_back( arcs.get_pt(0,index) );
SG_LOG(SG_GENERAL, SG_WARN, "exited at poly index = "
<< index << " " << arcs.get_pt(0,index));
// start with the 2nd item in the intersection list and
// traverse until we find another intersection
contour.push_back( arcs.get_pt(0, index) );
index = (index + 1) % arcs.contour_size(0);
// find which intersection we came out on in our list
SG_LOG(SG_GENERAL, SG_DEBUG, "finding exit intersection for " << index);
i = 0;
while ( i < (int)keep_ints.size() ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, " keep_int[" << i << "] = " << keep_ints[i]);
if ( index == keep_ints[i] ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " intersection index = " << i);
if ( index != keep_ints[start_int] ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " not start index so keep going");
keep_ints[i] = -1;
next_int = next_intersection( keep_ints, ignore_ints,
i+1 );
index = keep_ints[next_int];
keep_ints[next_int] = -1;
SG_LOG(SG_GENERAL, SG_DEBUG,
" next_int = " << next_int << " index = "
<< index);
}
break;
}
++i;
}
if ( i == (int)keep_ints.size() ) {
throw sg_exception("oops, didn't find that intersection, you are screwed");
}
}
keep_ints[start_int] = -1;
result.add_contour( contour, count );
count++;
while ( (arcs.get_pt(0, index).y() != y) ||
!valid_intersection(index, ignore_ints) ) {
contour.push_back( arcs.get_pt(0, index) );
index = (index + 1) % arcs.contour_size(0);
}
contour.push_back( arcs.get_pt(0, index) );
SG_LOG(SG_GENERAL, SG_WARN, "exited at poly index = "
<< index << " " << arcs.get_pt(0, index));
// find next keep_ints
start_int = next_intersection( keep_ints, ignore_ints, -1 );
next_int = next_intersection( keep_ints, ignore_ints, start_int+1 );
SG_LOG(SG_GENERAL, SG_DEBUG, "start_int = " << start_int);
SG_LOG(SG_GENERAL, SG_DEBUG, "next_int = " << next_int);
// find which intersection we came out on in our list
SG_LOG(SG_GENERAL, SG_DEBUG, "finding exit intersection for " << index);
i = 0;
while ( i < (int)keep_ints.size() ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, " keep_int[" << i << "] = " << keep_ints[i]);
if ( index == keep_ints[i] ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " intersection index = " << i);
if ( index != keep_ints[start_int] ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " not start index so keep going");
keep_ints[i] = -1;
next_int = next_intersection( keep_ints, ignore_ints,
i + 1 );
index = keep_ints[next_int];
keep_ints[next_int] = -1;
SG_LOG(SG_GENERAL, SG_DEBUG,
" next_int = " << next_int << " index = "
<< index);
}
break;
}
++i;
}
if ( i == (int)keep_ints.size() )
throw sg_exception("oops, didn't find that intersection, you are screwed");
}
keep_ints[start_int] = -1;
result.add_contour( contour, count );
count++;
// find next keep_ints
start_int = next_intersection( keep_ints, ignore_ints, -1 );
next_int = next_intersection( keep_ints, ignore_ints, start_int + 1 );
SG_LOG(SG_GENERAL, SG_DEBUG, "start_int = " << start_int);
SG_LOG(SG_GENERAL, SG_DEBUG, "next_int = " << next_int);
}
return true;
}
@ -533,16 +509,17 @@ static bool clip_contour( const TGPolygon& in, const double y,
// results. Doesn't work with holes. Returns true if routine thinks
// it was successful.
TGPolygon horizontal_clip( const TGPolygon& in, const double y,
const fgSideType side )
TGPolygon horizontal_clip( const TGPolygon& in, const double y,
const fgSideType side )
{
TGPolygon result;
result.erase();
// Step 1: sanity checks
if ( (int)in.contours() == 0 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "Error: 0 contour polygon");
return result;
SG_LOG(SG_GENERAL, SG_DEBUG, "Error: 0 contour polygon");
return result;
}
// clip each contour individually
@ -550,23 +527,23 @@ TGPolygon horizontal_clip( const TGPolygon& in, const double y,
point_list contour;
for ( int i = 0; i < in.contours(); ++i ) {
if ( (int)in.contour_size( i ) < 3 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "we must have at least three vertices to work");
return result;
}
if ( (int)in.contour_size( i ) < 3 ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "we must have at least three vertices to work");
return result;
}
tmp_poly.erase();
tmp_poly.erase();
contour = in.get_contour( i );
tmp_poly.add_contour( contour, 0 );
contour = in.get_contour( i );
tmp_poly.add_contour( contour, 0 );
clip_contour( tmp_poly, y, side, clip_poly );
clip_contour( tmp_poly, y, side, clip_poly );
// add each clip_poly contour to the result poly
for ( int j = 0; j < clip_poly.contours(); ++j ) {
contour = clip_poly.get_contour( j );
result.add_contour( contour, 0 );
}
// add each clip_poly contour to the result poly
for ( int j = 0; j < clip_poly.contours(); ++j ) {
contour = clip_poly.get_contour( j );
result.add_contour( contour, 0 );
}
}
return result;

View file

@ -44,7 +44,7 @@ enum fgSideType {
// results. Doesn't work with holes. Returns true if routine thinks
// it was successful.
TGPolygon horizontal_clip( const TGPolygon& in, const double y,
TGPolygon horizontal_clip( const TGPolygon& in, const double y,
const fgSideType side );

View file

@ -26,18 +26,20 @@
// Constructor
TGSuperPoly::TGSuperPoly() :
flag( "" )
flag( "" )
{
}
// Destructor
TGSuperPoly::~TGSuperPoly() {
TGSuperPoly::~TGSuperPoly()
{
}
// erase the "super" polygon
void TGSuperPoly::erase() {
void TGSuperPoly::erase()
{
material = "";
poly.erase();
normals.erase();

View file

@ -25,9 +25,9 @@
#define _SUPERPOLY_HXX
#ifndef __cplusplus
#ifndef __cplusplus
# error This library requires C++
#endif
#endif
#include <simgear/compiler.h>
@ -42,39 +42,75 @@ class TGSuperPoly {
private:
std::string material; // material/texture name
TGPolygon poly; // master polygon
TGPolygon normals; // corresponding normals
TGPolygon texcoords; // corresponding texture coordinates
TGPolygon tris; // triangulation
std::string flag; // For various potential record keeping needs
std::string material; // material/texture name
TGPolygon poly; // master polygon
TGPolygon normals; // corresponding normals
TGPolygon texcoords; // corresponding texture coordinates
TGPolygon tris; // triangulation
std::string flag; // For various potential record keeping needs
public:
// Constructor and destructor
TGSuperPoly( void );
~TGSuperPoly( void );
// Constructor and destructor
TGSuperPoly( void );
~TGSuperPoly( void );
inline std::string get_material() const { return material; }
inline void set_material( const std::string &m ) { material = m; }
inline std::string get_material() const
{
return material;
}
inline void set_material( const std::string &m )
{
material = m;
}
inline TGPolygon get_poly() const { return poly; }
inline void set_poly( const TGPolygon &p ) { poly = p; }
inline TGPolygon get_poly() const
{
return poly;
}
inline void set_poly( const TGPolygon &p )
{
poly = p;
}
inline TGPolygon get_normals() const { return normals; }
inline void set_normals( const TGPolygon &p ) { normals = p; }
inline TGPolygon get_normals() const
{
return normals;
}
inline void set_normals( const TGPolygon &p )
{
normals = p;
}
inline TGPolygon get_texcoords() const { return texcoords; }
inline void set_texcoords( const TGPolygon &p ) { texcoords = p; }
inline TGPolygon get_texcoords() const
{
return texcoords;
}
inline void set_texcoords( const TGPolygon &p )
{
texcoords = p;
}
inline TGPolygon get_tris() const { return tris; }
inline void set_tris( const TGPolygon &p ) { tris = p; }
inline TGPolygon get_tris() const
{
return tris;
}
inline void set_tris( const TGPolygon &p )
{
tris = p;
}
inline std::string get_flag() const { return flag; }
inline void set_flag( const std::string f ) { flag = f; }
inline std::string get_flag() const
{
return flag;
}
inline void set_flag( const std::string f )
{
flag = f;
}
// erase the polygon
void erase();
// erase the polygon
void erase();
};

View file

@ -26,9 +26,9 @@
#define _TEXPARAMS_HXX
#ifndef __cplusplus
#ifndef __cplusplus
# error This library requires C++
#endif
#endif
#include <simgear/compiler.h>
@ -40,55 +40,108 @@ class TGTexParams {
private:
Point3D ref;
double width;
double length;
double heading;
Point3D ref;
double width;
double length;
double heading;
double minu;
double maxu;
double minv;
double maxv;
double minu;
double maxu;
double minv;
double maxv;
public:
// Constructor and destructor
inline TGTexParams( void ) { }
inline TGTexParams( const Point3D &r, const double w, const double l,
const double h ) {
ref = r;
width = w;
length = l;
heading = h;
// Constructor and destructor
inline TGTexParams( void )
{
}
inline TGTexParams( const Point3D &r, const double w, const double l,
const double h )
{
ref = r;
width = w;
length = l;
heading = h;
minu = minv = 0.0;
maxu = maxv = 1.0;
}
inline ~TGTexParams( void ) { }
minu = minv = 0.0;
maxu = maxv = 1.0;
}
inline ~TGTexParams( void )
{
}
inline Point3D get_ref() const { return ref; }
inline void set_ref( const Point3D &r ) { ref = r; }
inline Point3D get_ref() const
{
return ref;
}
inline void set_ref( const Point3D &r )
{
ref = r;
}
inline double get_width() const { return width; }
inline void set_width( const double w ) { width = w; }
inline double get_width() const
{
return width;
}
inline void set_width( const double w )
{
width = w;
}
inline double get_length() const { return length; }
inline void set_length( const double l ) { length = l; }
inline double get_length() const
{
return length;
}
inline void set_length( const double l )
{
length = l;
}
inline double get_heading() const { return heading; }
inline void set_heading( const double h ) { heading = h; }
inline double get_heading() const
{
return heading;
}
inline void set_heading( const double h )
{
heading = h;
}
inline double get_minu() const { return minu; }
inline void set_minu( const double x ) { minu = x; }
inline double get_minu() const
{
return minu;
}
inline void set_minu( const double x )
{
minu = x;
}
inline double get_maxu() const { return maxu; }
inline void set_maxu( const double x ) { maxu = x; }
inline double get_maxu() const
{
return maxu;
}
inline void set_maxu( const double x )
{
maxu = x;
}
inline double get_minv() const { return minv; }
inline void set_minv( const double x ) { minv = x; }
inline double get_minv() const
{
return minv;
}
inline void set_minv( const double x )
{
minv = x;
}
inline double get_maxv() const { return maxv; }
inline void set_maxv( const double x ) { maxv = x; }
inline double get_maxv() const
{
return maxv;
}
inline void set_maxv( const double x )
{
maxv = x;
}
};