1
0
Fork 0

Working on generalized polygon tesselation.

This commit is contained in:
curt 2000-06-05 04:01:19 +00:00
parent b7d76af6c1
commit 5364692178
4 changed files with 158 additions and 10 deletions

View file

@ -1,6 +1,7 @@
noinst_LIBRARIES = libGeometry.a noinst_LIBRARIES = libGeometry.a
libGeometry_a_SOURCES = \ libGeometry_a_SOURCES = \
contour_tree.cxx contour_tree.cxx \
poly_support.cxx poly_support.hxx \ poly_support.cxx poly_support.hxx \
trinodes.cxx trinodes.hxx \ trinodes.cxx trinodes.hxx \
trisegs.cxx trisegs.hxx trisegs.cxx trisegs.hxx

View file

@ -36,6 +36,7 @@ extern "C" {
} }
#include <TriangleJRS/tri_support.h> #include <TriangleJRS/tri_support.h>
#include "contour_tree.hxx"
#include "poly_support.hxx" #include "poly_support.hxx"
#include "trinodes.hxx" #include "trinodes.hxx"
#include "trisegs.hxx" #include "trisegs.hxx"
@ -592,15 +593,14 @@ static Point3D point_inside_hole( point_list contour ) {
// Find a point inside a specific polygon contour taking holes into // Find a point inside a specific polygon contour taking holes into
// consideration // consideration
static Point3D point_inside_contour( const FGPolygon p, int contour ) { static Point3D point_inside_contour( FGContourNode *node, const FGPolygon &p ) {
point_list holes; point_list holes;
holes.clear(); holes.clear();
// build list of holes // build list of hole points
for ( int i = 0; i < p.contours(); ++i ) { for ( int i = 0; i < node->get_num_kids(); ++i ) {
if ( p.get_hole_flag( i ) ) { int contour_num = node->get_kid(i)->get_contour_num();
holes.push_back( p.get_point_inside( i ) ); holes.push_back( p.get_point_inside( contour_num ) );
}
} }
triele_list elelist = polygon_tesselate( p, contour ); triele_list elelist = polygon_tesselate( p, contour );
@ -624,9 +624,128 @@ static Point3D point_inside_contour( const FGPolygon p, int contour ) {
} }
// recurse the contour tree and build up the point inside list for
// each contour/hole
static void calc_point_inside( FGContourNode *node, FGPolygon &p ) {
for ( int i = 0; i < node->get_num_kids(); ++i ) {
if ( node->get_kid( i ) != NULL ) {
calc_point_inside( node->get_kid( i ), p );
}
}
Point3D pi = point_inside_contour( node, p );
}
static void print_contour_tree( FGContourNode *node, string indent ) {
cout << indent << node->get_contour_num() << endl;
indent += " ";
for ( int i = 0; i < node->get_num_kids(); ++i ) {
if ( node->get_kid( i ) != NULL ) {
print_contour_tree( node->get_kid( i ), indent );
}
}
}
// Build the contour "is inside of" tree
static void build_contour_tree( FGContourNode *node,
const FGPolygon &p,
int_list &avail )
{
cout << "working on contour = " << node->get_contour_num() << endl;
cout << " total contours = " << p.contours() << endl;
FGContourNode *tmp;
// see if we are building on a hole or note
bool flag;
if ( node->get_contour_num() > 0 ) {
flag = p.get_hole_flag( node->get_contour_num() );
} else {
flag = true;
}
// add all remaining hole/non-hole contours as children of the
// current node if they are inside of it.
for ( int i = 0; i < p.contours(); ++i ) {
cout << " testing contour = " << i << endl;
if ( p.get_hole_flag( i ) != flag ) {
// only holes can be children of non-holes and visa versa
if ( avail[i] ) {
// must still be an available contour
int cur_contour = node->get_contour_num();
if ( (cur_contour < 0 ) || p.is_inside( cur_contour, i ) ) {
// must be inside the parent (or if the parent is
// the root, add all available non-holes.
cout << " adding contour = " << i << endl;
avail[i] = 0;
tmp = new FGContourNode( i );
node->add_kid( tmp );
} else {
cout << " not inside" << endl;
}
} else {
cout << " not available" << endl;
}
} else {
cout << " wrong hole/non-hole type" << endl;
}
}
// if any of the children are inside of another child, remove the
// inside one
cout << "node now has num kids = " << node->get_num_kids() << endl;
for ( int i = 0; i < node->get_num_kids(); ++i ) {
for ( int j = 0; j < node->get_num_kids(); ++j ) {
if ( i != j ) {
if ( p.is_inside( i, j ) ) {
// need to remove contour j from the kid list
avail[ node->get_kid( i ) -> get_contour_num() ] = 1;
node->remove_kid( i );
cout << "removing kid " << i << " which is inside of kid "
<< j << endl;
}
} else {
// doesn't make sense to check if a contour is inside itself
}
}
}
// for each child, extend the contour tree
for ( int i = 0; i < node->get_num_kids(); ++i ) {
tmp = node->get_kid( i );
if ( tmp != NULL ) {
build_contour_tree( tmp, p, avail );
}
}
}
// calculate some "arbitrary" point inside the specified contour for // calculate some "arbitrary" point inside the specified contour for
// assigning attribute areas // assigning attribute areas
void calc_points_inside( FGPolygon& p ) { void calc_points_inside( FGPolygon& p ) {
// first build the contour tree
// make a list of all still available contours (all of the for
// starters)
int_list avail;
for ( int i = 0; i < p.contours(); ++i ) {
avail.push_back( 1 );
}
// create and initialize the root node
FGContourNode *ct = new FGContourNode( -1 );
// recursively build the tree
build_contour_tree( ct, p, avail );
print_contour_tree( ct, "" );
// recurse the tree and build up the point inside list for each
// contour/hole
calc_point_inside( ct, p );
// first calculate an inside point for all holes // first calculate an inside point for all holes
cout << "calculating points for poly with contours = " << p.contours() cout << "calculating points for poly with contours = " << p.contours()
<< endl; << endl;

View file

@ -81,7 +81,7 @@ static double calc_angle(point2d a, point2d b, point2d c) {
// i.e. non-self intersecting.) // i.e. non-self intersecting.)
// //
// negative areas indicate counter clockwise winding // negative areas indicate counter clockwise winding
// postitive areas indicate clockwise winding. // positive areas indicate clockwise winding.
double FGPolygon::area_contour( const int contour ) const { double FGPolygon::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)] // area = 1/2 * sum[i = 0 to k-1][x(i)*y(i+1) - x(i+1)*y(i)]
@ -101,7 +101,7 @@ double FGPolygon::area_contour( const int contour ) const {
} }
// return the smallest interior angle of the polygon // return the smallest interior angle of the contour
double FGPolygon::minangle_contour( const int contour ) { double FGPolygon::minangle_contour( const int contour ) {
point_list c = poly[contour]; point_list c = poly[contour];
int size = c.size(); int size = c.size();
@ -143,6 +143,31 @@ double FGPolygon::minangle_contour( const int contour ) {
} }
// return true if contour B is inside countour A
bool FGPolygon::is_inside( int a, int b ) const {
// make polygons from each specified contour
FGPolygon A, B;
point_list pl;
A.erase();
B.erase();
pl = get_contour( a );
A.add_contour( pl, 0 );
pl = get_contour( b );
B.add_contour( pl, 0 );
// B is "inside" A if the polygon_diff( B, A ) is not null.
FGPolygon result = polygon_diff( B, A );
cout << " is_inside() result = " << result.contours() << endl;
if ( result.contours() == 0 ) {
return true;
}
return false;
}
// shift every point in the polygon by lon, lat // shift every point in the polygon by lon, lat
void FGPolygon::shift( double lon, double lat ) { void FGPolygon::shift( double lon, double lat ) {
for ( int i = 0; i < (int)poly.size(); ++i ) { for ( int i = 0; i < (int)poly.size(); ++i ) {

View file

@ -141,12 +141,15 @@ public:
// i.e. non-self intersecting.) // i.e. non-self intersecting.)
// //
// negative areas indicate counter clockwise winding // negative areas indicate counter clockwise winding
// postitive areas indicate clockwise winding. // positive areas indicate clockwise winding.
double area_contour( const int contour ) const; double area_contour( const int contour ) const;
// return the smallest interior angle of the polygon // return the smallest interior angle of the contour
double minangle_contour( const int 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 // output
void write( const string& file ); void write( const string& file );
}; };