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

@ -49,8 +49,10 @@ 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 ) {
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;
@ -72,10 +74,9 @@ static void clip_and_write_poly( string root, long int p_index,
max.setx( 90.0 );
min.sety( -180.0 );
max.sety( 180.0 );
} else {
SG_LOG ( SG_GENERAL, SG_ALERT,
} 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 );
@ -96,26 +97,26 @@ static void clip_and_write_poly( string root, long int p_index,
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();
@ -133,12 +134,11 @@ static void clip_and_write_poly( string root, long int p_index,
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, "%d\n", result.contours() );
@ -147,13 +147,12 @@ static void clip_and_write_poly( string root, long int p_index,
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 ) {
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 );
}
}
@ -169,9 +168,8 @@ void tgChopNormalPolygon( const string& path, const string& poly_type,
int i, j;
// bail out immediately if polygon is empty
if ( shape.contours() == 0 ) {
if ( shape.contours() == 0 )
return;
}
min = Point3D( 200.0 );
max = Point3D( -200.0 );
@ -181,10 +179,7 @@ void tgChopNormalPolygon( const string& path, const string& poly_type,
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() );
}
}
@ -221,8 +216,8 @@ void tgChopNormalPolygon( const string& path, const string& poly_type,
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();
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);
@ -244,14 +239,13 @@ void tgChopNormalPolygon( const string& path, const string& poly_type,
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 ) {
else if ( clip_line < -89.0 )
clip_line = -89.0;
} else if ( clip_line >= 89.0 ) {
else if ( clip_line >= 89.0 )
clip_line = 90.0;
} else {
SG_LOG ( SG_GENERAL, SG_ALERT,
else {
SG_LOG( SG_GENERAL, SG_ALERT,
"Out of range latitude in clip_and_write_poly() = "
<< clip_line );
}
@ -263,7 +257,7 @@ void tgChopNormalPolygon( const string& path, const string& poly_type,
// structures to reduce memory use)
//
SG_LOG ( SG_GENERAL, SG_DEBUG,
SG_LOG( SG_GENERAL, SG_DEBUG,
"Generating bottom half (" << min.y() << "-" <<
clip_line << ")" );
@ -289,7 +283,7 @@ void tgChopNormalPolygon( const string& path, const string& poly_type,
// structures to reduce memory use)
//
SG_LOG ( SG_GENERAL, SG_DEBUG,
SG_LOG( SG_GENERAL, SG_DEBUG,
"Generating top half (" << clip_line << "-" <<
max.y() << ")" );
@ -322,9 +316,8 @@ void tgChopBigSimplePolygon( const string& path, const string& poly_type,
int i, j;
// bail out immediately if polygon is empty
if ( shape.contours() == 0 ) {
if ( shape.contours() == 0 )
return;
}
min = Point3D( 200.0 );
max = Point3D( -200.0 );
@ -334,10 +327,7 @@ void tgChopBigSimplePolygon( const string& path, const string& poly_type,
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() );
}
}
@ -396,14 +386,14 @@ 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) ) {
if ( (clip_line >= -89.0) && (clip_line < 89.0) )
clip_line += SG_HALF_BUCKET_SPAN;
} else if ( clip_line < -89.0 ) {
else if ( clip_line < -89.0 )
clip_line = -89.0;
} else if ( clip_line >= 89.0 ) {
else if ( clip_line >= 89.0 )
clip_line = 90.0;
} else {
SG_LOG ( SG_GENERAL, SG_ALERT,
else {
SG_LOG( SG_GENERAL, SG_ALERT,
"Out of range latitude in clip_and_write_poly() = "
<< clip_line );
}
@ -415,7 +405,7 @@ void tgChopBigSimplePolygon( const string& path, const string& poly_type,
// structures to reduce memory use)
//
SG_LOG ( SG_GENERAL, SG_DEBUG,
SG_LOG( SG_GENERAL, SG_DEBUG,
"Generating bottom half (" << min.y() << "-" <<
clip_line << ")" );
@ -430,9 +420,8 @@ void tgChopBigSimplePolygon( const string& path, const string& poly_type,
bottom.add_node( 0, Point3D(-180.0, clip_line, 0) );
bottom_clip = tgPolygonInt( bottom, shape );
} else {
} else
bottom_clip = horizontal_clip( shape, clip_line, Below );
}
tgChopBigSimplePolygon( path, poly_type, bottom_clip, preserve3d );
}
@ -444,7 +433,7 @@ void tgChopBigSimplePolygon( const string& path, const string& poly_type,
// structures to reduce memory use)
//
SG_LOG ( SG_GENERAL, SG_DEBUG,
SG_LOG( SG_GENERAL, SG_DEBUG,
"Generating top half (" << clip_line << "-" <<
max.y() << ")" );
@ -459,9 +448,8 @@ void tgChopBigSimplePolygon( const string& path, const string& poly_type,
top.add_node( 0, Point3D(-180.0, max.y(), 0) );
top_clip = tgPolygonInt( top, shape );
} else {
} else
top_clip = horizontal_clip( shape, clip_line, Above );
}
tgChopBigSimplePolygon( path, poly_type, top_clip, preserve3d );
}

View file

@ -35,7 +35,8 @@ 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" );
@ -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 ) {
if ( fp == NULL )
SG_LOG(SG_GENERAL, SG_ALERT,
"Error cannot open " << poly_path << " for writing");
}
fprintf( fp, "%ld\n", poly_index );

View file

@ -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 {
union {
double x;
double dist;
double lon;
};
union {
};
union {
double y;
double theta;
double lat;
};
};
};
#endif // TG_POINT2D_HXX

View file

@ -25,7 +25,9 @@
//
// http://www.cs.man.ac.uk/aig/staff/alan/software/
//
extern "C" {
#include <gpc.h>
}
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
@ -48,15 +50,18 @@ TGPolygon::TGPolygon( void )
// Destructor
TGPolygon::~TGPolygon( void ) {
TGPolygon::~TGPolygon( void )
{
}
// 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 TGPolygon::inherit_elevations( const TGPolygon &source ) {
void TGPolygon::inherit_elevations( const TGPolygon &source )
{
TGTriNodes nodes;
nodes.clear();
int i, j;
@ -94,43 +99,39 @@ void TGPolygon::inherit_elevations( const TGPolygon &source ) {
last = -9999.0;
for ( j = 0; j < (int)poly[i].size(); ++j ) {
Point3D p = poly[i][j];
if ( p.z() > -9000 ) {
if ( p.z() > -9000 )
last = p.z();
} else {
if ( last > -9000 ) {
else if ( last > -9000 )
poly[i][j].setz( last );
}
}
}
// go back ways
last = -9999.0;
for ( j = poly[i].size() - 1; j >= 0; --j ) {
Point3D p = poly[i][j];
if ( p.z() > -9000 ) {
if ( p.z() > -9000 )
last = p.z();
} else {
if ( last > -9000 ) {
else if ( last > -9000 )
poly[i][j].setz( last );
}
}
}
}
}
// Set the elevations of all points to the specified values
void TGPolygon::set_elevations( double elev ) {
for ( unsigned i = 0; i < poly.size(); ++i ) {
for ( unsigned int j = 0; j < poly[i].size(); ++j ) {
void TGPolygon::set_elevations( double elev )
{
for ( unsigned i = 0; i < poly.size(); ++i )
for ( unsigned int j = 0; j < poly[i].size(); ++j )
poly[i][j].setz( elev );
}
}
}
// Calculate theta of angle (a, b, c)
double tgPolygonCalcAngle(point2d a, point2d b, point2d c) {
double tgPolygonCalcAngle(point2d a, point2d b, point2d c)
{
point2d u, v;
double udist, vdist, uv_dot, tmp;
@ -162,7 +163,8 @@ double tgPolygonCalcAngle(point2d a, point2d b, point2d c) {
// negative areas indicate counter clockwise winding
// positive areas indicate clockwise winding.
double TGPolygon::area_contour( const int contour ) const {
double TGPolygon::area_contour( const int contour ) const
{
// area = 1/2 * sum[i = 0 to k-1][x(i)*y(i+1) - x(i+1)*y(i)]
// where i=k is defined as i=0
@ -170,9 +172,8 @@ double TGPolygon::area_contour( const int contour ) const {
int size = c.size();
double sum = 0.0;
for ( int i = 0; i < size; ++i ) {
sum += c[(i+1)%size].x() * c[i].y() - c[i].x() * c[(i+1)%size].y();
}
for ( int i = 0; i < size; ++i )
sum += c[(i + 1) % size].x() * c[i].y() - c[i].x() * c[(i + 1) % size].y();
// area can be negative or positive depending on the polygon
// winding order
@ -181,7 +182,8 @@ double TGPolygon::area_contour( const int contour ) const {
// return the smallest interior angle of the contour
double TGPolygon::minangle_contour( const int contour ) {
double TGPolygon::minangle_contour( const int contour )
{
point_list c = poly[contour];
int size = c.size();
int p1_index, p2_index, p3_index;
@ -191,16 +193,14 @@ double TGPolygon::minangle_contour( const int contour ) {
for ( int i = 0; i < size; ++i ) {
p1_index = i - 1;
if ( p1_index < 0 ) {
if ( p1_index < 0 )
p1_index += size;
}
p2_index = i;
p3_index = i + 1;
if ( p3_index >= size ) {
if ( p3_index >= size )
p3_index -= size;
}
p1.x = c[p1_index].x();
p1.y = c[p1_index].y();
@ -213,20 +213,21 @@ double TGPolygon::minangle_contour( const int contour ) {
angle = tgPolygonCalcAngle( p1, p2, p3 );
if ( angle < min_angle ) {
if ( angle < min_angle )
min_angle = angle;
}
}
return min_angle;
}
// return true if contour A is inside countour B
bool TGPolygon::is_inside( int a, int b ) const {
bool TGPolygon::is_inside( int a, int b ) const
{
// make polygons from each specified contour
TGPolygon A, B;
point_list pl;
A.erase();
B.erase();
@ -248,10 +249,9 @@ bool TGPolygon::is_inside( int a, int b ) const {
// char junk;
// cin >> junk;
if ( result.contours() == 0 ) {
if ( result.contours() == 0 )
// SG_LOG(SG_GENERAL, SG_DEBUG, " " << a << " is_inside() " << b);
return true;
}
// SG_LOG(SG_GENERAL, SG_DEBUG, " " << a << " not is_inside() " << b);
return false;
@ -259,7 +259,8 @@ bool TGPolygon::is_inside( int a, int b ) const {
// shift every point in the polygon by lon, lat
void TGPolygon::shift( double lon, double lat ) {
void TGPolygon::shift( double lon, double lat )
{
for ( int i = 0; i < (int)poly.size(); ++i ) {
for ( int j = 0; j < (int)poly[i].size(); ++j ) {
poly[i][j].setx( poly[i][j].x() + lon );
@ -270,15 +271,15 @@ void TGPolygon::shift( double lon, double lat ) {
// output
void TGPolygon::write( const string& file ) const {
void TGPolygon::write( const string& file ) const
{
FILE *fp = fopen( file.c_str(), "w" );
fprintf(fp, "%d\n", poly.size());
for ( int i = 0; i < (int)poly.size(); ++i ) {
fprintf(fp, "%d\n", poly[i].size());
for ( int j = 0; j < (int)poly[i].size(); ++j ) {
for ( int j = 0; j < (int)poly[i].size(); ++j )
fprintf(fp, "%.6f %.6f\n", poly[i][j].x(), poly[i][j].y());
}
fprintf(fp, "%.6f %.6f\n", poly[i][0].x(), poly[i][0].y());
}
@ -287,35 +288,32 @@ void TGPolygon::write( const string& file ) const {
// output
void TGPolygon::write_contour( const int contour, const string& file ) const {
void TGPolygon::write_contour( const int contour, const string& file ) const
{
FILE *fp = fopen( file.c_str(), "w" );
for ( int j = 0; j < (int)poly[contour].size(); ++j ) {
for ( int j = 0; j < (int)poly[contour].size(); ++j )
fprintf(fp, "%.6f %.6f\n", poly[contour][j].x(), poly[contour][j].y());
}
fclose(fp);
}
// Set operation type
typedef enum {
POLY_DIFF, // Difference
POLY_INT, // Intersection
POLY_XOR, // Exclusive or
POLY_UNION // Union
} clip_op;
#ifdef CLIP_GPC
//
// wrapper functions for gpc polygon clip routines
//
// Make a gpc_poly from an TGPolygon
void make_gpc_poly( const TGPolygon& in, gpc_polygon *out ) {
void make_gpc_poly( const TGPolygon& in, gpc_polygon *out )
{
gpc_vertex_list v_list;
v_list.num_vertices = 0;
v_list.vertex = new gpc_vertex[FG_MAX_VERTICES];
// SG_LOG(SG_GENERAL, SG_DEBUG, "making a gpc_poly");
// SG_LOG(SG_GENERAL, SG_DEBUG, " input contours = " << in.contours());
Point3D p;
// build the gpc_polygon structures
for ( int i = 0; i < in.contours(); ++i ) {
@ -326,14 +324,6 @@ void make_gpc_poly( const TGPolygon& in, gpc_polygon *out ) {
throw sg_exception(message);;
}
#if 0
SG_LOG(SG_GENERAL, SG_ALERT,
" make_clipper_poly : processing contour " << i << ", nodes = "
<< in.contour_size(i) << ", hole = "
<< in.get_hole_flag(i)
);
#endif
for ( int j = 0; j < in.contour_size( i ); ++j ) {
p = in.get_pt( i, j );
v_list.vertex[j].x = p.x();
@ -347,17 +337,15 @@ void make_gpc_poly( const TGPolygon& in, gpc_polygon *out ) {
delete [] v_list.vertex;
}
void make_tg_poly( const gpc_polygon* in, TGPolygon *out )
{
for ( int i = 0; i < in->num_contours; ++i ) {
for ( int j = 0; j < in->contour[i].num_vertices; j++ ) {
Point3D p( in->contour[i].vertex[j].x, in->contour[i].vertex[j].y, -9999.0 );
out->add_node(i, p);
}
out->set_hole_flag( i, in->hole[i] );
}
}
// Set operation type
typedef enum {
POLY_DIFF, // Difference
POLY_INT, // Intersection
POLY_XOR, // Exclusive or
POLY_UNION // Union
} clip_op;
// Generic clipping routine
TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject,
@ -366,6 +354,7 @@ TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject,
TGPolygon result;
gpc_polygon *gpc_subject = new gpc_polygon;
gpc_subject->num_contours = 0;
gpc_subject->contour = NULL;
gpc_subject->hole = NULL;
@ -383,21 +372,44 @@ TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject,
gpc_result->hole = NULL;
gpc_op op;
if ( poly_op == POLY_DIFF ) {
if ( poly_op == POLY_DIFF )
op = GPC_DIFF;
} else if ( poly_op == POLY_INT ) {
else if ( poly_op == POLY_INT )
op = GPC_INT;
} else if ( poly_op == POLY_XOR ) {
else if ( poly_op == POLY_XOR )
op = GPC_XOR;
} else if ( poly_op == POLY_UNION ) {
else if ( poly_op == POLY_UNION )
op = GPC_UNION;
} else {
else
throw sg_exception("Unknown polygon op, exiting.");
}
gpc_polygon_clip( op, gpc_subject, gpc_clip, gpc_result );
make_tg_poly( gpc_result, &result );
for ( int i = 0; i < gpc_result->num_contours; ++i ) {
// SG_LOG(SG_GENERAL, SG_DEBUG,
// " processing contour = " << i << ", nodes = "
// << gpc_result->contour[i].num_vertices << ", hole = "
// << gpc_result->hole[i]);
// sprintf(junkn, "g.%d", junkc++);
// junkfp = fopen(junkn, "w");
for ( int j = 0; j < gpc_result->contour[i].num_vertices; j++ ) {
Point3D p( gpc_result->contour[i].vertex[j].x,
gpc_result->contour[i].vertex[j].y,
-9999.0 );
// junkp = in_nodes.get_node( index );
// fprintf(junkfp, "%.4f %.4f\n", junkp.x(), junkp.y());
result.add_node(i, p);
// SG_LOG(SG_GENERAL, SG_DEBUG, " - " << index);
}
// fprintf(junkfp, "%.4f %.4f\n",
// gpc_result->contour[i].vertex[0].x,
// gpc_result->contour[i].vertex[0].y);
// fclose(junkfp);
result.set_hole_flag( i, gpc_result->hole[i] );
}
// free allocated memory
gpc_free_polygon( gpc_subject );
@ -407,322 +419,40 @@ TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject,
return result;
}
// Generic clipping routine
TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const gpc_polygon& clip )
{
TGPolygon result;
gpc_polygon *gpc_subject = new gpc_polygon;
gpc_subject->num_contours = 0;
gpc_subject->contour = NULL;
gpc_subject->hole = NULL;
make_gpc_poly( subject, gpc_subject );
gpc_polygon *gpc_clip = (gpc_polygon*)&clip;
gpc_polygon *gpc_result = new gpc_polygon;
gpc_result->num_contours = 0;
gpc_result->contour = NULL;
gpc_result->hole = NULL;
gpc_op op;
if ( poly_op == POLY_DIFF ) {
op = GPC_DIFF;
} else if ( poly_op == POLY_INT ) {
op = GPC_INT;
} else if ( poly_op == POLY_XOR ) {
op = GPC_XOR;
} else if ( poly_op == POLY_UNION ) {
op = GPC_UNION;
} else {
throw sg_exception("Unknown polygon op, exiting.");
}
gpc_polygon_clip( op, gpc_subject, gpc_clip, gpc_result );
make_tg_poly( gpc_result, &result );
// free allocated memory
gpc_free_polygon( gpc_subject );
gpc_free_polygon( gpc_result );
return result;
}
gpc_polygon polygon_clip_keep_native_fmt( clip_op poly_op, const TGPolygon& subject, const gpc_polygon& clip )
{
gpc_polygon *gpc_subject = new gpc_polygon;
gpc_subject->num_contours = 0;
gpc_subject->contour = NULL;
gpc_subject->hole = NULL;
make_gpc_poly( subject, gpc_subject );
gpc_polygon *gpc_clip = (gpc_polygon*)&clip;
gpc_polygon result;
result.num_contours = 0;
result.contour = NULL;
result.hole = NULL;
gpc_op op;
if ( poly_op == POLY_DIFF ) {
op = GPC_DIFF;
} else if ( poly_op == POLY_INT ) {
op = GPC_INT;
} else if ( poly_op == POLY_XOR ) {
op = GPC_XOR;
} else if ( poly_op == POLY_UNION ) {
op = GPC_UNION;
} else {
throw sg_exception("Unknown polygon op, exiting.");
}
gpc_polygon_clip( op, gpc_subject, gpc_clip, &result );
// free allocated memory
gpc_free_polygon( gpc_subject );
return result;
}
#endif
#ifdef CLIP_CLIPPER
#define FIXEDPT (10000000000000)
IntPoint MakeClipperPoint( Point3D pt )
{
long64 x, y;
x = (long64)( pt.x() * FIXEDPT );
y = (long64)( pt.y() * FIXEDPT );
return IntPoint( x, y );
}
Point3D MakeTGPoint( IntPoint pt )
{
double x, y;
x = (double)( ((double)pt.X) / (double)FIXEDPT );
y = (double)( ((double)pt.Y) / (double)FIXEDPT );
return Point3D( x, y, -9999.0f);
}
void make_clipper_poly( const TGPolygon& in, Polygons *out )
{
Polygon contour;
Point3D p;
int i, j;
if (in.contours())
{
// assume contour 0 is boundary, 1..x are holes
// create the boundary
for (j=0; j<in.contour_size(0); ++j)
{
p = in.get_pt( 0, j );
contour.push_back(MakeClipperPoint(p));
}
out->push_back(contour);
// create the holes
for (i=1; i<in.contours(); ++i )
{
contour.clear();
for (j=0; j<in.contour_size(i); ++j)
{
p = in.get_pt( i, j );
contour.push_back(MakeClipperPoint(p));
}
out->push_back(contour);
}
}
}
void make_tg_poly( const ExPolygons& in, TGPolygon *out )
{
int res_contour = 0;
out->erase();
for (int i=0; i<in.size(); i++)
{
const struct ExPolygon* pg = &in[i];
IntPoint ip;
// Get the boundary contour
for (int j = 0; j < pg->outer.size(); j++)
{
ip = IntPoint( pg->outer[j].X, pg->outer[j].Y );
out->add_node(res_contour, MakeTGPoint(ip));
}
out->set_hole_flag(res_contour, 0);
res_contour++;
// then the holes
for (int j = 0; j < pg->holes.size(); j++)
{
for (int k = 0; k < pg->holes[j].size(); k++)
{
ip = IntPoint( pg->holes[j].at(k).X, pg->holes[j].at(k).Y );
out->add_node(res_contour, MakeTGPoint(ip));
}
out->set_hole_flag(res_contour, 1);
res_contour++;
}
}
}
TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const TGPolygon& clip )
{
TGPolygon result;
Polygons clipper_subject;
make_clipper_poly( subject, &clipper_subject );
Polygons clipper_clip;
make_clipper_poly( clip, &clipper_clip );
ExPolygons clipper_result;
ClipType op;
if ( poly_op == POLY_DIFF ) {
op = ctDifference;
} else if ( poly_op == POLY_INT ) {
op = ctIntersection;
} else if ( poly_op == POLY_XOR ) {
op = ctXor;
} else if ( poly_op == POLY_UNION ) {
op = ctUnion;
} else {
throw sg_exception("Unknown polygon op, exiting.");
}
Clipper c;
c.Clear();
c.AddPolygons(clipper_subject, ptSubject);
c.AddPolygons(clipper_clip, ptClip);
c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd);
make_tg_poly( clipper_result, &result );
return result;
}
TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const Polygons& clipper_clip )
{
TGPolygon result;
Polygons clipper_subject;
make_clipper_poly( subject, &clipper_subject );
ExPolygons clipper_result;
ClipType op;
if ( poly_op == POLY_DIFF ) {
op = ctDifference;
} else if ( poly_op == POLY_INT ) {
op = ctIntersection;
} else if ( poly_op == POLY_XOR ) {
op = ctXor;
} else if ( poly_op == POLY_UNION ) {
op = ctUnion;
} else {
throw sg_exception("Unknown polygon op, exiting.");
}
Clipper c;
c.Clear();
c.AddPolygons(clipper_subject, ptSubject);
c.AddPolygons(clipper_clip, ptClip);
c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd);
make_tg_poly( clipper_result, &result );
return result;
}
Polygons polygon_clip_keep_native_fmt( clip_op poly_op, const TGPolygon& subject, const Polygons& clipper_clip )
{
Polygons clipper_subject;
make_clipper_poly( subject, &clipper_subject );
ExPolygons clipper_result;
Polygons result;
ClipType op;
if ( poly_op == POLY_DIFF ) {
op = ctDifference;
} else if ( poly_op == POLY_INT ) {
op = ctIntersection;
} else if ( poly_op == POLY_XOR ) {
op = ctXor;
} else if ( poly_op == POLY_UNION ) {
op = ctUnion;
} else {
throw sg_exception("Unknown polygon op, exiting.");
}
Clipper c;
c.Clear();
c.AddPolygons(clipper_subject, ptSubject);
c.AddPolygons(clipper_clip, ptClip);
c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd);
// copy contours to polygons structure
for (int i=0; i<clipper_result.size(); i++)
{
result.push_back( clipper_result[i].outer );
for (int j=0; j<clipper_result[i].holes.size(); j++)
{
result.push_back( clipper_result[i].holes[j] );
}
}
return result;
}
#endif
// Difference
TGPolygon tgPolygonDiff( const TGPolygon& subject, const TGPolygon& clip ) {
TGPolygon tgPolygonDiff( const TGPolygon& subject, const TGPolygon& clip )
{
return polygon_clip( POLY_DIFF, subject, clip );
}
#if CLIP_NATIVE
TGPolygon tgPolygonDiff( const TGPolygon& subject, const ClipPolyType& clip ) {
return polygon_clip( POLY_DIFF, subject, clip );
}
#endif
// Intersection
TGPolygon tgPolygonInt( const TGPolygon& subject, const TGPolygon& clip ) {
TGPolygon tgPolygonInt( const TGPolygon& subject, const TGPolygon& clip )
{
return polygon_clip( POLY_INT, subject, clip );
}
// Exclusive or
TGPolygon tgPolygonXor( const TGPolygon& subject, const TGPolygon& clip ) {
TGPolygon tgPolygonXor( const TGPolygon& subject, const TGPolygon& clip )
{
return polygon_clip( POLY_XOR, subject, clip );
}
// Union
TGPolygon tgPolygonUnion( const TGPolygon& subject, const TGPolygon& clip ) {
TGPolygon tgPolygonUnion( const TGPolygon& subject, const TGPolygon& clip )
{
return polygon_clip( POLY_UNION, subject, clip );
}
#if CLIP_NATIVE
ClipPolyType tgPolygonUnion( const TGPolygon& subject, const ClipPolyType& clip ) {
return polygon_clip_keep_native_fmt( POLY_UNION, subject, clip );
}
#endif
// canonify the polygon winding, outer contour must be anti-clockwise,
// all inner contours must be clockwise.
TGPolygon polygon_canonify( const TGPolygon& in_poly ) {
TGPolygon polygon_canonify( const TGPolygon& in_poly )
{
TGPolygon result;
result.erase();
// Negative areas indicate counter clockwise winding. Postitive
@ -743,22 +473,19 @@ TGPolygon polygon_canonify( const TGPolygon& in_poly ) {
// reverse contour
point_list rcontour;
rcontour.clear();
for ( int j = (int)contour.size() - 1; j >= 0; --j ) {
for ( int j = (int)contour.size() - 1; j >= 0; --j )
rcontour.push_back( contour[j] );
}
result.add_contour( rcontour, hole_flag );
} else if ( !hole_flag && (area > 0) ) {
// reverse contour
point_list rcontour;
rcontour.clear();
for ( int j = (int)contour.size() - 1; j >= 0; --j ) {
for ( int j = (int)contour.size() - 1; j >= 0; --j )
rcontour.push_back( contour[j] );
}
result.add_contour( rcontour, hole_flag );
} else {
} else
result.add_contour( contour, hole_flag );
}
}
return result;
}
@ -766,7 +493,8 @@ TGPolygon polygon_canonify( const TGPolygon& in_poly ) {
// Traverse a polygon and split edges until they are less than max_len
// (specified in meters)
TGPolygon tgPolygonSplitLongEdges( const TGPolygon &poly, double max_len ) {
TGPolygon tgPolygonSplitLongEdges( const TGPolygon &poly, double max_len )
{
TGPolygon result;
Point3D p0, p1;
int i, j, k;
@ -782,8 +510,7 @@ TGPolygon tgPolygonSplitLongEdges( const TGPolygon &poly, double max_len ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " " << p0 << " - " << p1);
if ( fabs(p0.y()) < (90.0 - SG_EPSILON)
|| fabs(p1.y()) < (90.0 - SG_EPSILON) )
{
|| fabs(p1.y()) < (90.0 - SG_EPSILON) ) {
double az1, az2, s;
geo_inverse_wgs_84( 0.0,
p0.y(), p0.x(), p1.y(), p1.x(),
@ -850,7 +577,8 @@ TGPolygon tgPolygonSplitLongEdges( const TGPolygon &poly, double max_len ) {
// Traverse a polygon and return the union of all the non-hole contours
TGPolygon tgPolygonStripHoles( const TGPolygon &poly ) {
TGPolygon tgPolygonStripHoles( const TGPolygon &poly )
{
TGPolygon result; result.erase();
SG_LOG(SG_GENERAL, SG_DEBUG, "strip_out_holes()");
@ -858,7 +586,7 @@ TGPolygon tgPolygonStripHoles( const TGPolygon &poly ) {
for ( int i = 0; i < poly.contours(); ++i ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, "contour = " << i);
point_list contour = poly.get_contour( i );
if ( ! poly.get_hole_flag(i) ) {
if ( !poly.get_hole_flag(i) ) {
TGPolygon tmp;
tmp.add_contour( contour, poly.get_hole_flag(i) );
result = tgPolygonUnion( tmp, result );
@ -868,163 +596,20 @@ TGPolygon tgPolygonStripHoles( const TGPolygon &poly ) {
return result;
}
#if 0
// Wrapper for the fast Polygon Triangulation based on Seidel's
// Algorithm by Atul Narkhede and Dinesh Manocha
// http://www.cs.unc.edu/~dm/CODE/GEM/chapter.html
// I make this oversize because given an n sided concave polygon with
// m, n, o, ... sided holes, I have no idea how many triangles would
// result and I don't have time right now to see if an upper bound can
// be determined easily.
#define FG_MAX_TRIANGLES 100000
TGPolygon polygon_to_tristrip( const TGPolygon& in_poly ) {
int i, j;
// canonify the polygon winding, outer contour must be
// anti-clockwise, all inner contours must be clockwise.
TGPolygon canon_poly = polygon_canonify( in_poly );
// create and fill in the required structures
int ncontours = canon_poly.contours();
int cntr[ncontours];
int vsize = 1;
for ( i = 0; i < canon_poly.contours(); ++i ) {
cntr[i] = canon_poly.contour_size( i );
vsize += cntr[i];
}
double vertices[vsize][2];
int counter = 1;
Point3D p;
for ( i = 0; i < canon_poly.contours(); ++i ) {
for ( j = 0; j < canon_poly.contour_size( i ); ++j ) {
p = canon_poly.get_pt( i, j );
vertices[counter][0] = p.x();
vertices[counter][1] = p.y();
counter++;
}
}
int triangles[FG_MAX_TRIANGLES][3];
// do the triangulation
int ntriangles = triangulate_polygon(ncontours, cntr, vertices, triangles);
/*
gpc_polygon *tmp_poly = new gpc_polygon;
tmp_poly->num_contours = 0;
tmp_poly->contour = NULL;
tmp_poly->hole = NULL;
make_gpc_poly( in_poly, tmp_poly );
gpc_tristrip *tmp_tristrip = new gpc_tristrip;
tmp_tristrip->num_strips = 0;
tmp_tristrip->strip = NULL;
gpc_polygon_to_tristrip( tmp_poly, tmp_tristrip );
TGPolygon result;
for ( int i = 0; i < tmp_tristrip->num_strips; ++i ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " processing strip = "
<< i << ", nodes = "
<< tmp_tristrip->strip[i].num_vertices);
// sprintf(junkn, "g.%d", junkc++);
// junkfp = fopen(junkn, "w");
for ( int j = 0; j < tmp_tristrip->strip[i].num_vertices; j++ ) {
Point3D p( tmp_tristrip->strip[i].vertex[j].x,
tmp_tristrip->strip[i].vertex[j].y,
0 );
// junkp = in_nodes.get_node( index );
// fprintf(junkfp, "%.4f %.4f\n", junkp.x(), junkp.y());
result.add_node(i, p);
// SG_LOG(SG_GENERAL, SG_DEBUG, " - " << index);
}
// fprintf(junkfp, "%.4f %.4f\n",
// gpc_result->contour[i].vertex[0].x,
// gpc_result->contour[i].vertex[0].y);
// fclose(junkfp);
}
// free allocated memory
gpc_free_polygon( tmp_poly );
gpc_free_tristrip( tmp_tristrip );
*/
// return result;
}
#endif
#if 0
//
// wrapper functions for gpc polygon to tristrip routine
//
TGPolygon polygon_to_tristrip_old( const TGPolygon& in_poly ) {
gpc_polygon *tmp_poly = new gpc_polygon;
tmp_poly->num_contours = 0;
tmp_poly->contour = NULL;
tmp_poly->hole = NULL;
make_gpc_poly( in_poly, tmp_poly );
gpc_tristrip *tmp_tristrip = new gpc_tristrip;
tmp_tristrip->num_strips = 0;
tmp_tristrip->strip = NULL;
gpc_polygon_to_tristrip( tmp_poly, tmp_tristrip );
TGPolygon result;
for ( int i = 0; i < tmp_tristrip->num_strips; ++i ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " processing strip = "
<< i << ", nodes = "
<< tmp_tristrip->strip[i].num_vertices);
// sprintf(junkn, "g.%d", junkc++);
// junkfp = fopen(junkn, "w");
for ( int j = 0; j < tmp_tristrip->strip[i].num_vertices; j++ ) {
Point3D p( tmp_tristrip->strip[i].vertex[j].x,
tmp_tristrip->strip[i].vertex[j].y,
0 );
// junkp = in_nodes.get_node( index );
// fprintf(junkfp, "%.4f %.4f\n", junkp.x(), junkp.y());
result.add_node(i, p);
// SG_LOG(SG_GENERAL, SG_DEBUG, " - " << index);
}
// fprintf(junkfp, "%.4f %.4f\n",
// gpc_result->contour[i].vertex[0].x,
// gpc_result->contour[i].vertex[0].y);
// fclose(junkfp);
}
// free allocated memory
gpc_free_polygon( tmp_poly );
gpc_free_tristrip( tmp_tristrip );
return result;
}
#endif
// Send a polygon to standard output.
ostream &
operator<< (ostream &output, const TGPolygon &poly)
operator<<(ostream &output, const TGPolygon &poly)
{
int nContours = poly.contours();
output << nContours << endl;
for (int i = 0; i < nContours; i++) {
int nPoints = poly.contour_size(i);
output << nPoints << endl;
output << poly.get_hole_flag(i) << endl;
for (int j = 0; j < nPoints; j++) {
for (int j = 0; j < nPoints; j++)
output << poly.get_pt(i, j) << endl;
}
}
return output; // MSVC
}

View file

@ -86,31 +86,35 @@ 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 ) {
// 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 {
// 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 ) {
// 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();
@ -118,10 +122,11 @@ public:
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 ) {
// 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;
@ -133,89 +138,103 @@ public:
}
}
poly[contour].push_back( p );
}
}
// return size
inline int contours() const { return poly.size(); }
inline int contour_size( int contour ) const {
// 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 {
}
inline int total_size() const
{
int size = 0;
for ( int i = 0; i < contours(); ++i ) {
for ( int i = 0; i < contours(); ++i )
size += poly[i].size();
}
return size;
}
}
// return the ith point from the specified contour
inline Point3D get_pt( int contour, int i ) const {
// return the ith point from the specified contour
inline Point3D get_pt( int contour, int i ) const
{
return poly[contour][i];
}
}
// update the value of a point
inline void set_pt( int contour, int i, const Point3D& p ) {
// update the value of a point
inline void set_pt( int contour, int i, const Point3D& p )
{
poly[contour][i] = p;
}
}
// get and set an arbitrary point inside the specified polygon contour
inline Point3D get_point_inside( const int contour ) const {
// 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 ) {
}
inline void set_point_inside( int contour, const Point3D& p )
{
inside_list[contour] = p;
}
}
// get and set hole flag
inline int get_hole_flag( const int contour ) const {
// 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 ) {
}
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++) {
}
inline bool has_holes() const
{
for (int i = 0; i < contours(); i++)
if (get_hole_flag(i))
return true;
}
return false;
}
}
// 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 );
// 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 );
// Set the elevations of all points to the specified values
void set_elevations( double elev );
// Set the elevations of all points to the specified values
void set_elevations( double elev );
// shift every point in the polygon by lon, lat
void shift( double lon, double lat );
// shift every point in the polygon by lon, lat
void shift( double lon, double lat );
// erase
inline void erase() { poly.clear(); }
// erase
inline void erase()
{
poly.clear();
}
// informational
// informational
// 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 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 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;
// 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( 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,7 +37,8 @@
// 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;
@ -45,10 +46,9 @@ static bool intersects_y( Point3D p0, Point3D p1, double y, Point3D *result ) {
p1 = tmp;
}
if ( (y < p0.y()) || (y > p1.y()) ) {
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):
//
@ -57,23 +57,19 @@ static bool intersects_y( Point3D p0, Point3D p1, double y, Point3D *result ) {
double x;
if ( fabs(p0.y() - p1.y()) > CLIP_EPSILON ) {
if ( fabs(p0.y() - p1.y()) > CLIP_EPSILON )
x = p1.x() + (y - p1.y()) * (p0.x() - p1.x()) / (p0.y() - p1.y());
} else {
else
return false;
}
result->setx(x);
result->sety(y);
if ( p0.x() <= p1.x() ) {
if ( (p0.x() <= x) && (x <= p1.x()) ) {
if ( (p0.x() <= x) && (x <= p1.x()) )
return true;
}
} else {
if ( (p0.x() >= x) && (x >= p1.x()) ) {
} else if ( (p0.x() >= x) && (x >= p1.x()) )
return true;
}
}
return false;
}
@ -81,7 +77,8 @@ 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;
@ -108,11 +105,9 @@ 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] ) {
for ( int i = 0; i < (int)ignore_ints.size(); ++i )
if ( intersection == ignore_ints[i] )
return false;
}
}
return true;
}
@ -124,14 +119,12 @@ static int next_intersection( const int_list& keep_ints,
{
// 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() ) {
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) ) {
if ( keep_ints[i] != -1 )
if ( valid_intersection(keep_ints[i], ignore_ints) )
return i;
}
}
++i;
}
@ -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 ) {
if ( p.y() >= line )
return true;
}
} else if ( side == Below ) {
if ( p.y() <= line ) {
} 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 ) {
if ( p.y() > line )
return true;
}
} else if ( side == Below ) {
if ( p.y() < line ) {
} else if ( side == Below )
if ( p.y() < line )
return true;
}
}
return false;
}
@ -184,7 +173,7 @@ 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 );
@ -197,10 +186,10 @@ static bool simple_clip( const TGPolygon& in, const double y,
}
if ( is_on_or_inside(y, p, side) ) {
if ( is_on_or_inside(y, p_last, 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 {
else {
if ( !intersects_y(p, p_last, y, &p_int) ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "Huh, this should have intersected!");
return false;
@ -212,8 +201,7 @@ static bool simple_clip( const TGPolygon& in, const double y,
// 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) )
{
(fabs(p.y() - p_int.y()) < CLIP_EPSILON) ) {
// SG_LOG(SG_GENERAL, SG_DEBUG,
// "WARNING: p and p_int are identical, "
// << "omitting p");
@ -233,17 +221,15 @@ static bool simple_clip( const TGPolygon& in, const double y,
// "intersection inside to outside " << i << " "
// << p_int);
if ( (fabs(p.x() - p_int.x()) < CLIP_EPSILON) &&
(fabs(p.y() - p_int.y()) < 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 {
} else
result.add_node( 0, p_int );
}
}
}
}
p_last = p;
}
@ -273,8 +259,7 @@ static bool build_intersections( const TGPolygon& arcs, double line,
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);
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 = "
@ -283,8 +268,7 @@ static bool build_intersections( const TGPolygon& arcs, double line,
<< arcs.get_pt(0, after));
if ( side == Above ) {
if ( (arcs.get_pt(0, before).y() > line) &&
(arcs.get_pt(0, after).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");
@ -293,8 +277,7 @@ static bool build_intersections( const TGPolygon& arcs, double line,
ignore_ints.push_back( index );
}
if ( (arcs.get_pt(0, before).y() <= line) &&
(arcs.get_pt(0, after).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"
@ -304,16 +287,14 @@ static bool build_intersections( const TGPolygon& arcs, double line,
}
} else if ( side == Below ) {
if ( (arcs.get_pt(0, before).y() >= line) &&
(arcs.get_pt(0, after).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) )
{
(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.");
@ -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;
@ -341,9 +323,8 @@ TGPolygon fix_dups( TGPolygon& in ) {
y = in.get_pt(0, i).y();
if ( (x == x_last) && (y == y_last) ) {
// ignore
} else {
} else
result.add_node(0, in.get_pt(0, i));
}
x_last = x;
y_last = y;
}
@ -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 ) {
if ( result_arcs.contours() > 0 )
SG_LOG(SG_GENERAL, SG_DEBUG, "result_arcs size = "
<< result_arcs.total_size());
} else {
else
SG_LOG(SG_GENERAL, SG_DEBUG, "empty result");
}
} else {
} else
throw sg_exception("simple_clip_above() failed!");
}
// Step 3: check for trivial cases
@ -412,7 +391,7 @@ static bool clip_contour( const TGPolygon& in, const double y,
// 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;
@ -431,9 +410,8 @@ static bool clip_contour( const TGPolygon& in, const double y,
Point3D p = result_arcs.get_pt( 0, i );
tmp.add_node( 0, p );
}
} else {
} 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);
@ -463,7 +441,7 @@ static bool clip_contour( const TGPolygon& in, const double y,
index = keep_ints[next_int];
keep_ints[next_int] = -1;
SG_LOG(SG_GENERAL, SG_DEBUG, "\nstarting at point = "
<< arcs.get_pt(0,index));
<< arcs.get_pt(0, index));
while ( index != keep_ints[start_int] ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "index = " << index
@ -472,18 +450,17 @@ static bool clip_contour( const TGPolygon& in, const double y,
// start with the 2nd item in the intersection list and
// traverse until we find another intersection
contour.push_back( arcs.get_pt(0,index) );
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) );
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) );
contour.push_back( arcs.get_pt(0, index) );
SG_LOG(SG_GENERAL, SG_WARN, "exited at poly index = "
<< index << " " << arcs.get_pt(0,index));
<< index << " " << arcs.get_pt(0, index));
// find which intersection we came out on in our list
SG_LOG(SG_GENERAL, SG_DEBUG, "finding exit intersection for " << index);
@ -496,7 +473,7 @@ static bool clip_contour( const TGPolygon& in, const double y,
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 );
i + 1 );
index = keep_ints[next_int];
keep_ints[next_int] = -1;
SG_LOG(SG_GENERAL, SG_DEBUG,
@ -507,17 +484,16 @@ static bool clip_contour( const TGPolygon& in, const double y,
}
++i;
}
if ( i == (int)keep_ints.size() ) {
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 );
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);
@ -537,6 +513,7 @@ TGPolygon horizontal_clip( const TGPolygon& in, const double y,
const fgSideType side )
{
TGPolygon result;
result.erase();
// Step 1: sanity checks

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

@ -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

@ -40,22 +40,25 @@ 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 ) {
// 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;
@ -63,32 +66,82 @@ public:
minu = minv = 0.0;
maxu = maxv = 1.0;
}
inline ~TGTexParams( void ) { }
}
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;
}
};