Working on generalized polygon tesselation.
This commit is contained in:
parent
b7d76af6c1
commit
5364692178
4 changed files with 158 additions and 10 deletions
|
@ -1,6 +1,7 @@
|
|||
noinst_LIBRARIES = libGeometry.a
|
||||
|
||||
libGeometry_a_SOURCES = \
|
||||
contour_tree.cxx contour_tree.cxx \
|
||||
poly_support.cxx poly_support.hxx \
|
||||
trinodes.cxx trinodes.hxx \
|
||||
trisegs.cxx trisegs.hxx
|
||||
|
|
|
@ -36,6 +36,7 @@ extern "C" {
|
|||
}
|
||||
#include <TriangleJRS/tri_support.h>
|
||||
|
||||
#include "contour_tree.hxx"
|
||||
#include "poly_support.hxx"
|
||||
#include "trinodes.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
|
||||
// consideration
|
||||
static Point3D point_inside_contour( const FGPolygon p, int contour ) {
|
||||
static Point3D point_inside_contour( FGContourNode *node, const FGPolygon &p ) {
|
||||
point_list holes;
|
||||
holes.clear();
|
||||
|
||||
// build list of holes
|
||||
for ( int i = 0; i < p.contours(); ++i ) {
|
||||
if ( p.get_hole_flag( i ) ) {
|
||||
holes.push_back( p.get_point_inside( i ) );
|
||||
}
|
||||
// build list of hole points
|
||||
for ( int i = 0; i < node->get_num_kids(); ++i ) {
|
||||
int contour_num = node->get_kid(i)->get_contour_num();
|
||||
holes.push_back( p.get_point_inside( contour_num ) );
|
||||
}
|
||||
|
||||
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
|
||||
// assigning attribute areas
|
||||
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
|
||||
cout << "calculating points for poly with contours = " << p.contours()
|
||||
<< endl;
|
||||
|
|
|
@ -81,7 +81,7 @@ static double calc_angle(point2d a, point2d b, point2d c) {
|
|||
// i.e. non-self intersecting.)
|
||||
//
|
||||
// negative areas indicate counter clockwise winding
|
||||
// postitive areas indicate clockwise winding.
|
||||
// positive areas indicate clockwise winding.
|
||||
|
||||
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)]
|
||||
|
@ -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 ) {
|
||||
point_list c = poly[contour];
|
||||
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
|
||||
void FGPolygon::shift( double lon, double lat ) {
|
||||
for ( int i = 0; i < (int)poly.size(); ++i ) {
|
||||
|
|
|
@ -141,12 +141,15 @@ public:
|
|||
// i.e. non-self intersecting.)
|
||||
//
|
||||
// negative areas indicate counter clockwise winding
|
||||
// postitive areas indicate clockwise winding.
|
||||
// positive areas indicate clockwise winding.
|
||||
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 );
|
||||
|
||||
// return true if contour B is inside countour A
|
||||
bool is_inside( int a, int b ) const;
|
||||
|
||||
// output
|
||||
void write( const string& file );
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue