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
|
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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
|
|
@ -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 );
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue