Bring in textured roads, streams, and railroads.
- use ogr-decode with new option --texture-lines to generate polygons with texture info - possible fix for triangulation errors when triangulating each poly by itself. (It's worked for me, but more testing needed) - Still using GPC for clipping. CLIPPER adds time, and looks to have more errors. More testing needed here as well. Simply edit the #define in polygon.h to choose clipping library. Major TODOs: 1) There is 1 tile (with the most heavy OSM data) that blows up, and I get huge road textured polys all over the place. Must be an overrun somewhere. 2) Lake / Ocean smoothing. The current algorithm handles all nodes at once. I'm going to need to modify for the new structure 3) neighbor tile matching. This actually doesn't look so bad without it implemented. The old method would add points in the triangulator. If a point was added on the tile boundary, a t-junction would be created. Points are no longer added in triangulation, so the polygon splitting in ogr-decode should make the points equal on each side of the tile boundary. (I haven't seen any t-junctions, at least) 4) cleanup - this is a bit of a mess. I really want to refactor to make the code more understandable.
This commit is contained in:
parent
a6058dff58
commit
de5dbfd6a5
3 changed files with 137 additions and 67 deletions
|
@ -81,6 +81,7 @@ public:
|
||||||
static Point3D fromSGVec3(const SGVec3<double>& cart);
|
static Point3D fromSGVec3(const SGVec3<double>& cart);
|
||||||
static Point3D fromSGVec3(const SGVec3<float>& cart);
|
static Point3D fromSGVec3(const SGVec3<float>& cart);
|
||||||
static Point3D fromSGVec2(const SGVec2<double>& cart);
|
static Point3D fromSGVec2(const SGVec2<double>& cart);
|
||||||
|
static Point3D fromSGVec2(const SGVec2<float>& cart);
|
||||||
|
|
||||||
// Assignment operators
|
// Assignment operators
|
||||||
|
|
||||||
|
@ -245,6 +246,16 @@ inline Point3D Point3D::fromSGVec2(const SGVec2<double>& cart)
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Point3D Point3D::fromSGVec2(const SGVec2<float>& cart)
|
||||||
|
{
|
||||||
|
Point3D pt;
|
||||||
|
pt.setx(cart.x());
|
||||||
|
pt.sety(cart.y());
|
||||||
|
pt.setz(0);
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ASSIGNMENT OPERATORS
|
// ASSIGNMENT OPERATORS
|
||||||
|
|
||||||
inline Point3D& Point3D::operator = (const Point3D& p)
|
inline Point3D& Point3D::operator = (const Point3D& p)
|
||||||
|
|
|
@ -56,6 +56,7 @@ using std::ostream_iterator;
|
||||||
using std::sort;
|
using std::sort;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
|
#if 0 // unused
|
||||||
// Given a line segment specified by two endpoints p1 and p2, return
|
// Given a line segment specified by two endpoints p1 and p2, return
|
||||||
// the slope of the line.
|
// the slope of the line.
|
||||||
static double slope( const Point3D& p0, const Point3D& p1 ) {
|
static double slope( const Point3D& p0, const Point3D& p1 ) {
|
||||||
|
@ -66,8 +67,9 @@ static double slope( const Point3D& p0, const Point3D& p1 ) {
|
||||||
return DBL_MAX;
|
return DBL_MAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0 // unused
|
||||||
// Given a line segment specified by two endpoints p1 and p2, return
|
// Given a line segment specified by two endpoints p1 and p2, return
|
||||||
// the y value of a point on the line that intersects with the
|
// the y value of a point on the line that intersects with the
|
||||||
// verticle line through x. Return true if an intersection is found,
|
// verticle line through x. Return true if an intersection is found,
|
||||||
|
@ -111,16 +113,21 @@ static bool intersects( Point3D p0, Point3D p1, double x, Point3D *result ) {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// basic triangulation of a polygon with out adding points or
|
// basic triangulation of a polygon with out adding points or
|
||||||
// splitting edges, this should triangulate around interior holes.
|
// splitting edges, this should triangulate around interior holes.
|
||||||
void polygon_tesselate( const TGPolygon &p,
|
void polygon_tesselate( const TGPolygon &p,
|
||||||
|
const point_list &extra_nodes,
|
||||||
triele_list &elelist,
|
triele_list &elelist,
|
||||||
point_list &out_pts )
|
point_list &out_pts,
|
||||||
|
string tri_flags )
|
||||||
{
|
{
|
||||||
struct triangulateio in, out, vorout;
|
struct triangulateio in, out, vorout;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
tri_flags = "pzqenXYYQ";
|
||||||
|
|
||||||
// make sure all elements of these structs point to "NULL"
|
// make sure all elements of these structs point to "NULL"
|
||||||
zero_triangulateio( &in );
|
zero_triangulateio( &in );
|
||||||
zero_triangulateio( &out );
|
zero_triangulateio( &out );
|
||||||
|
@ -132,62 +139,77 @@ void polygon_tesselate( const TGPolygon &p,
|
||||||
double max_x = p.get_pt(0,0).x();
|
double max_x = p.get_pt(0,0).x();
|
||||||
|
|
||||||
int total_pts = 0;
|
int total_pts = 0;
|
||||||
|
int total_segments = 0;
|
||||||
|
|
||||||
for ( i = 0; i < p.contours(); ++i ) {
|
for ( i = 0; i < p.contours(); ++i ) {
|
||||||
total_pts += p.contour_size( i );
|
total_pts += p.contour_size( i );
|
||||||
}
|
}
|
||||||
|
total_segments = total_pts;
|
||||||
|
total_pts += extra_nodes.size();
|
||||||
|
|
||||||
in.numberofpoints = total_pts;
|
in.numberofpoints = total_pts;
|
||||||
in.pointlist = (REAL *) malloc(in.numberofpoints * 2 * sizeof(REAL));
|
in.pointlist = (REAL *) malloc(in.numberofpoints * 2 * sizeof(REAL));
|
||||||
|
|
||||||
counter = 0;
|
counter = 0;
|
||||||
for ( i = 0; i < p.contours(); ++i ) {
|
for ( i = 0; i < p.contours(); ++i ) {
|
||||||
point_list contour = p.get_contour( i );
|
point_list contour = p.get_contour( i );
|
||||||
for ( int j = 0; j < (int)contour.size(); ++j ) {
|
for ( int j = 0; j < (int)contour.size(); ++j ) {
|
||||||
in.pointlist[2*counter] = contour[j].x();
|
in.pointlist[2*counter] = contour[j].x();
|
||||||
in.pointlist[2*counter + 1] = contour[j].y();
|
in.pointlist[2*counter + 1] = contour[j].y();
|
||||||
if ( contour[j].x() > max_x ) {
|
/* remember largest x value of the polygon to
|
||||||
max_x = contour[j].x();
|
* easily calc outside point
|
||||||
}
|
*/
|
||||||
++counter;
|
if ( contour[j].x() > max_x ) {
|
||||||
}
|
max_x = contour[j].x();
|
||||||
|
}
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < (int)extra_nodes.size(); ++i ) {
|
||||||
|
in.pointlist[2*counter] = extra_nodes[i].x();
|
||||||
|
in.pointlist[2*counter + 1] = extra_nodes[i].y();
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the node attribute to elevation data */
|
||||||
in.numberofpointattributes = 1;
|
in.numberofpointattributes = 1;
|
||||||
in.pointattributelist = (REAL *) malloc(in.numberofpoints *
|
in.pointattributelist = (REAL *) malloc(in.numberofpoints *
|
||||||
in.numberofpointattributes *
|
in.numberofpointattributes *
|
||||||
sizeof(REAL));
|
sizeof(REAL));
|
||||||
counter = 0;
|
counter = 0;
|
||||||
for ( i = 0; i < p.contours(); ++i ) {
|
for ( i = 0; i < p.contours(); ++i ) {
|
||||||
point_list contour = p.get_contour( i );
|
point_list contour = p.get_contour( i );
|
||||||
for ( int j = 0; j < (int)contour.size(); ++j ) {
|
for ( int j = 0; j < (int)contour.size(); ++j ) {
|
||||||
in.pointattributelist[counter] = contour[j].z();
|
in.pointattributelist[counter] = contour[j].z();
|
||||||
++counter;
|
++counter;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < (int)extra_nodes.size(); ++i ) {
|
||||||
|
in.pointattributelist[counter] = extra_nodes[i].z();
|
||||||
|
++counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
// in.pointmarkerlist = (int *) malloc(in.numberofpoints * sizeof(int));
|
|
||||||
// for ( i = 0; i < in.numberofpoints; ++i) {
|
|
||||||
// in.pointmarkerlist[i] = 0;
|
|
||||||
// }
|
|
||||||
in.pointmarkerlist = NULL;
|
in.pointmarkerlist = NULL;
|
||||||
|
|
||||||
// segment list
|
// segment list
|
||||||
in.numberofsegments = in.numberofpoints;
|
in.numberofsegments = total_segments;
|
||||||
in.segmentlist = (int *) malloc(in.numberofsegments * 2 * sizeof(int));
|
in.segmentlist = (int *) malloc(in.numberofsegments * 2 * sizeof(int));
|
||||||
counter = 0;
|
counter = 0;
|
||||||
start = 0;
|
start = 0;
|
||||||
end = -1;
|
end = -1;
|
||||||
|
|
||||||
for ( i = 0; i < p.contours(); ++i ) {
|
for ( i = 0; i < p.contours(); ++i ) {
|
||||||
point_list contour = p.get_contour( i );
|
point_list contour = p.get_contour( i );
|
||||||
start = end + 1;
|
start = end + 1;
|
||||||
end = start + contour.size() - 1;
|
end = start + contour.size() - 1;
|
||||||
for ( int j = 0; j < (int)contour.size() - 1; ++j ) {
|
for ( int j = 0; j < (int)contour.size() - 1; ++j ) {
|
||||||
in.segmentlist[counter++] = j + start;
|
in.segmentlist[counter++] = j + start;
|
||||||
in.segmentlist[counter++] = j + start + 1;
|
in.segmentlist[counter++] = j + start + 1;
|
||||||
}
|
}
|
||||||
in.segmentlist[counter++] = end;
|
in.segmentlist[counter++] = end;
|
||||||
in.segmentlist[counter++] = start;
|
in.segmentlist[counter++] = start;
|
||||||
}
|
}
|
||||||
|
|
||||||
in.segmentmarkerlist = (int *) malloc(in.numberofsegments * sizeof(int));
|
in.segmentmarkerlist = (int *) malloc(in.numberofsegments * sizeof(int));
|
||||||
|
@ -198,21 +220,22 @@ void polygon_tesselate( const TGPolygon &p,
|
||||||
// hole list
|
// hole list
|
||||||
in.numberofholes = 1;
|
in.numberofholes = 1;
|
||||||
for ( i = 0; i < p.contours(); ++i ) {
|
for ( i = 0; i < p.contours(); ++i ) {
|
||||||
if ( p.get_hole_flag( i ) ) {
|
if ( p.get_hole_flag( i ) ) {
|
||||||
++in.numberofholes;
|
++in.numberofholes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in.holelist = (REAL *) malloc(in.numberofholes * 2 * sizeof(REAL));
|
in.holelist = (REAL *) malloc(in.numberofholes * 2 * sizeof(REAL));
|
||||||
|
|
||||||
// outside of polygon
|
// outside of polygon
|
||||||
counter = 0;
|
counter = 0;
|
||||||
in.holelist[counter++] = max_x + 1.0;
|
in.holelist[counter++] = max_x + 1.0;
|
||||||
in.holelist[counter++] = 0.0;
|
in.holelist[counter++] = 0.0;
|
||||||
|
|
||||||
for ( i = 0; i < (int)p.contours(); ++i ) {
|
for ( i = 0; i < (int)p.contours(); ++i ) {
|
||||||
if ( p.get_hole_flag( i ) ) {
|
if ( p.get_hole_flag( i ) ) {
|
||||||
in.holelist[counter++] = p.get_point_inside(i).x();
|
in.holelist[counter++] = p.get_point_inside(i).x();
|
||||||
in.holelist[counter++] = p.get_point_inside(i).y();
|
in.holelist[counter++] = p.get_point_inside(i).y();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// region list
|
// region list
|
||||||
|
@ -249,12 +272,7 @@ void polygon_tesselate( const TGPolygon &p,
|
||||||
// no new points on boundary (Y), no internal segment
|
// no new points on boundary (Y), no internal segment
|
||||||
// splitting (YY), no quality refinement (q)
|
// splitting (YY), no quality refinement (q)
|
||||||
// Quite (Q)
|
// Quite (Q)
|
||||||
|
triangulate( (char *)tri_flags.c_str(), &in, &out, &vorout );
|
||||||
string tri_options;
|
|
||||||
tri_options = "pzYYenQ"; // add multiple "V" entries for verbosity
|
|
||||||
//cout << "Triangulation with options = " << tri_options << endl;
|
|
||||||
|
|
||||||
triangulate( (char *)tri_options.c_str(), &in, &out, &vorout );
|
|
||||||
|
|
||||||
// TEMPORARY
|
// TEMPORARY
|
||||||
// write_tri_data(&out);
|
// write_tri_data(&out);
|
||||||
|
@ -267,27 +285,26 @@ void polygon_tesselate( const TGPolygon &p,
|
||||||
int n1, n2, n3;
|
int n1, n2, n3;
|
||||||
double attribute;
|
double attribute;
|
||||||
for ( i = 0; i < out.numberoftriangles; ++i ) {
|
for ( i = 0; i < out.numberoftriangles; ++i ) {
|
||||||
n1 = out.trianglelist[i * 3];
|
n1 = out.trianglelist[i * 3];
|
||||||
n2 = out.trianglelist[i * 3 + 1];
|
n2 = out.trianglelist[i * 3 + 1];
|
||||||
n3 = out.trianglelist[i * 3 + 2];
|
n3 = out.trianglelist[i * 3 + 2];
|
||||||
if ( out.numberoftriangleattributes > 0 ) {
|
if ( out.numberoftriangleattributes > 0 ) {
|
||||||
attribute = out.triangleattributelist[i];
|
attribute = out.triangleattributelist[i];
|
||||||
} else {
|
} else {
|
||||||
attribute = 0.0;
|
attribute = 0.0;
|
||||||
}
|
}
|
||||||
// cout << "triangle = " << n1 << " " << n2 << " " << n3 << endl;
|
// cout << "triangle = " << n1 << " " << n2 << " " << n3 << endl;
|
||||||
|
elelist.push_back( TGTriEle( n1, n2, n3, attribute ) );
|
||||||
elelist.push_back( TGTriEle( n1, n2, n3, attribute ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// output points
|
// output points
|
||||||
out_pts.clear();
|
out_pts.clear();
|
||||||
double x, y, z;
|
double x, y, z;
|
||||||
for ( i = 0; i < out.numberofpoints; ++i ) {
|
for ( i = 0; i < out.numberofpoints; ++i ) {
|
||||||
x = out.pointlist[i * 2 ];
|
x = out.pointlist[i * 2 ];
|
||||||
y = out.pointlist[i * 2 + 1];
|
y = out.pointlist[i * 2 + 1];
|
||||||
z = out.pointattributelist[i];
|
z = out.pointattributelist[i];
|
||||||
out_pts.push_back( Point3D(x, y, z) );
|
out_pts.push_back( Point3D(x, y, z) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// free mem allocated to the "Triangle" structures
|
// free mem allocated to the "Triangle" structures
|
||||||
|
@ -321,6 +338,7 @@ void polygon_tesselate( const TGPolygon &p,
|
||||||
|
|
||||||
TGPolygon polygon_tesselate_alt( TGPolygon &p ) {
|
TGPolygon polygon_tesselate_alt( TGPolygon &p ) {
|
||||||
TGPolygon result;
|
TGPolygon result;
|
||||||
|
point_list extra_nodes;
|
||||||
result.erase();
|
result.erase();
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -340,7 +358,8 @@ TGPolygon polygon_tesselate_alt( TGPolygon &p ) {
|
||||||
// 2. Do a final triangulation of the entire polygon
|
// 2. Do a final triangulation of the entire polygon
|
||||||
triele_list trieles;
|
triele_list trieles;
|
||||||
point_list nodes;
|
point_list nodes;
|
||||||
polygon_tesselate( p, trieles, nodes );
|
// polygon_tesselate( p, extra_nodes, trieles, nodes, "pzYYenQ" );
|
||||||
|
polygon_tesselate( p, extra_nodes, trieles, nodes, "pzenQ" );
|
||||||
|
|
||||||
// 3. Convert the tesselated output to a list of tringles.
|
// 3. Convert the tesselated output to a list of tringles.
|
||||||
// basically a polygon with a contour for every triangle
|
// basically a polygon with a contour for every triangle
|
||||||
|
@ -357,6 +376,41 @@ TGPolygon polygon_tesselate_alt( TGPolygon &p ) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p, const point_list& extra_nodes ) {
|
||||||
|
TGPolygon result;
|
||||||
|
result.erase();
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Bail right away if polygon is empty
|
||||||
|
if ( p.contours() == 0 ) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Robustly find a point inside each contour that is not
|
||||||
|
// inside any other contour
|
||||||
|
calc_points_inside( p );
|
||||||
|
for ( i = 0; i < p.contours(); ++i );
|
||||||
|
|
||||||
|
// 2. Do a final triangulation of the entire polygon
|
||||||
|
triele_list trieles;
|
||||||
|
point_list nodes;
|
||||||
|
polygon_tesselate( p, extra_nodes, trieles, nodes, "pzenQ" );
|
||||||
|
|
||||||
|
// 3. Convert the tesselated output to a list of tringles.
|
||||||
|
// basically a polygon with a contour for every triangle
|
||||||
|
for ( i = 0; i < (int)trieles.size(); ++i ) {
|
||||||
|
TGTriEle t = trieles[i];
|
||||||
|
Point3D p1 = nodes[ t.get_n1() ];
|
||||||
|
Point3D p2 = nodes[ t.get_n2() ];
|
||||||
|
Point3D p3 = nodes[ t.get_n3() ];
|
||||||
|
result.add_node( i, p1 );
|
||||||
|
result.add_node( i, p2 );
|
||||||
|
result.add_node( i, p3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find all intersections of the given contour with the x-parallel line at
|
* Find all intersections of the given contour with the x-parallel line at
|
||||||
* y=yline. Assume that no points are on the line (callers take care of this!).
|
* y=yline. Assume that no points are on the line (callers take care of this!).
|
||||||
|
@ -369,7 +423,7 @@ static void intersect_yline_with_contour( double yline, TGContourNode *node, TGP
|
||||||
|
|
||||||
// cout << "intersect_yline_with_contour() yline=" << yline << endl;
|
// cout << "intersect_yline_with_contour() yline=" << yline << endl;
|
||||||
|
|
||||||
for ( int i = 0; i < count; ++i ) {
|
for ( int i = 0; i < (int)count; ++i ) {
|
||||||
const Point3D &p0 = pts[ i ];
|
const Point3D &p0 = pts[ i ];
|
||||||
const Point3D &p1 = pts[ ( i + 1 ) % count ];
|
const Point3D &p1 = pts[ ( i + 1 ) % count ];
|
||||||
|
|
||||||
|
@ -404,7 +458,7 @@ static void write_tree_element( TGContourNode *node, TGPolygon& p, int hole=0) {
|
||||||
|
|
||||||
if (contour_num != -1) {
|
if (contour_num != -1) {
|
||||||
char buf[256];
|
char buf[256];
|
||||||
sprintf(buf, "failed/element%ld.poly",contour_num);
|
sprintf(buf, "failed/element%d.poly",contour_num);
|
||||||
FILE *treefp = fopen(buf,"w");
|
FILE *treefp = fopen(buf,"w");
|
||||||
|
|
||||||
fprintf(treefp,"#2D\n");
|
fprintf(treefp,"#2D\n");
|
||||||
|
@ -412,7 +466,7 @@ static void write_tree_element( TGContourNode *node, TGPolygon& p, int hole=0) {
|
||||||
|
|
||||||
fprintf(treefp,"1\n");
|
fprintf(treefp,"1\n");
|
||||||
|
|
||||||
fprintf(treefp,"%ld\n",p.contour_size(contour_num));
|
fprintf(treefp,"%d\n",p.contour_size(contour_num));
|
||||||
fprintf(treefp,"%d\n",hole);
|
fprintf(treefp,"%d\n",hole);
|
||||||
|
|
||||||
for (int i=0;i<p.contour_size(contour_num);i++) {
|
for (int i=0;i<p.contour_size(contour_num);i++) {
|
||||||
|
@ -487,7 +541,7 @@ static void calc_point_inside( TGContourNode *node, TGPolygon &p ) {
|
||||||
Point3D lastpt=*point_it;
|
Point3D lastpt=*point_it;
|
||||||
|
|
||||||
double maxdiff=0.0;
|
double maxdiff=0.0;
|
||||||
double yline; // the y-location of the intersection line
|
double yline=0.0; // the y-location of the intersection line
|
||||||
|
|
||||||
while ((++point_it) != allpoints.end()) {
|
while ((++point_it) != allpoints.end()) {
|
||||||
double diff=point_it->y()-lastpt.y();
|
double diff=point_it->y()-lastpt.y();
|
||||||
|
@ -526,7 +580,7 @@ static void calc_point_inside( TGContourNode *node, TGPolygon &p ) {
|
||||||
|
|
||||||
double maxlen=0.0;
|
double maxlen=0.0;
|
||||||
int longest=0;
|
int longest=0;
|
||||||
for ( int i = 0; i < xcuts.size(); i+=2 ) {
|
for ( int i = 0; i < (int)xcuts.size(); i+=2 ) {
|
||||||
double x0 = xcuts[ i ];
|
double x0 = xcuts[ i ];
|
||||||
double x1 = xcuts[ i + 1 ];
|
double x1 = xcuts[ i + 1 ];
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,10 @@ inline double triangle_area( const Point3D p1,
|
||||||
// basic triangulation of a polygon with out adding points or
|
// basic triangulation of a polygon with out adding points or
|
||||||
// splitting edges
|
// splitting edges
|
||||||
void polygon_tesselate( const TGPolygon &p,
|
void polygon_tesselate( const TGPolygon &p,
|
||||||
|
const point_list &extra_nodes,
|
||||||
triele_list &elelist,
|
triele_list &elelist,
|
||||||
point_list &out_pts );
|
point_list &out_pts,
|
||||||
|
std::string flags );
|
||||||
|
|
||||||
// Alternate basic triangulation of a polygon with out adding points
|
// Alternate basic triangulation of a polygon with out adding points
|
||||||
// or splitting edges and without regard for holes. Returns a polygon
|
// or splitting edges and without regard for holes. Returns a polygon
|
||||||
|
@ -64,6 +66,9 @@ void polygon_tesselate( const TGPolygon &p,
|
||||||
// will modify the points_inside list for your polygon.
|
// will modify the points_inside list for your polygon.
|
||||||
TGPolygon polygon_tesselate_alt( TGPolygon &p );
|
TGPolygon polygon_tesselate_alt( TGPolygon &p );
|
||||||
|
|
||||||
|
TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p,
|
||||||
|
const point_list &extra_nodes );
|
||||||
|
|
||||||
// calculate some "arbitrary" point inside each of the polygons contours
|
// calculate some "arbitrary" point inside each of the polygons contours
|
||||||
void calc_points_inside( TGPolygon& p );
|
void calc_points_inside( TGPolygon& p );
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue