]> git.mxchange.org Git - flightgear.git/commitdiff
Initial revision.
authorcurt <curt>
Mon, 1 Mar 1999 15:39:39 +0000 (15:39 +0000)
committercurt <curt>
Mon, 1 Mar 1999 15:39:39 +0000 (15:39 +0000)
Clipper/Makefile.am [new file with mode: 0644]
Clipper/clipper.cxx [new file with mode: 0644]
Clipper/clipper.hxx [new file with mode: 0644]
Clipper/main.cxx [new file with mode: 0644]

diff --git a/Clipper/Makefile.am b/Clipper/Makefile.am
new file mode 100644 (file)
index 0000000..21d1948
--- /dev/null
@@ -0,0 +1,14 @@
+noinst_LIBRARIES = libClipper.a
+bin_PROGRAMS = clipper
+
+libClipper_a_SOURCES = clipper.cxx clipper.hxx
+clipper_SOURCES = main.cxx
+
+clipper_LDADD = $(top_builddir)/Tools/Clipper/libClipper.a \
+       $(top_builddir)/Tools/Polygon/libPolygon.a \
+       $(top_builddir)/Lib/Debug/libDebug.a \
+       $(top_builddir)/Lib/Misc/libMisc.a \
+       $(top_builddir)/Lib/zlib/libz.a \
+       -lgfc -lgpc
+
+INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Tools
diff --git a/Clipper/clipper.cxx b/Clipper/clipper.cxx
new file mode 100644 (file)
index 0000000..e4aaa76
--- /dev/null
@@ -0,0 +1,226 @@
+// clipper.cxx -- top level routines to take a series of arbitrary areas and
+//                produce a tight fitting puzzle pieces that combine to make a
+//                tile
+//
+// Written by Curtis Olson, started February 1999.
+//
+// Copyright (C) 1999  Curtis L. Olson  - curt@flightgear.org
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+// (Log is kept at end of this file)
+
+
+#include "clipper.hxx"
+
+#include <Debug/logstream.hxx>
+#include <Include/fg_constants.h>
+#include <Misc/fgstream.hxx>
+#include <Polygon/names.hxx>
+
+
+#define EXTRA_SAFETY_CLIP
+
+#define FG_MAX_VERTICES 100000
+
+static gpc_vertex_list v_list;
+// static gpc_polygon poly;
+static FGPolyList polys_in, polys_out;
+
+
+// Initialize Clipper (allocate and/or connect structures)
+bool fgClipperInit() {
+    v_list.num_vertices = 0;
+    v_list.vertex = new gpc_vertex[FG_MAX_VERTICES];;
+
+    return true;
+}
+
+
+// Load a polygon definition file
+bool fgClipperLoadPolygons(const string& path) {
+    string poly_name;
+    AreaType poly_type;
+    int contours, count, i, j;
+    double startx, starty, x, y, lastx, lasty;
+
+    FG_LOG( FG_CLIPPER, FG_INFO, "Loading " << path << " ..." );
+
+    fg_gzifstream in( path );
+
+    if ( !in ) {
+        FG_LOG( FG_CLIPPER, FG_ALERT, "Cannot open file: " << path );
+       exit(-1);
+    }
+
+    in >> skipcomment;
+    while ( !in.eof() ) {
+       in >> poly_name;
+       cout << "poly name = " << poly_name << endl;
+       poly_type = get_area_type( poly_name );
+       cout << "poly type (int) = " << (int)poly_type << endl;
+       in >> contours;
+       cout << "num contours = " << contours << endl;
+
+       for ( i = 0; i < contours; ++i ) {
+           in >> count;
+
+           if ( count < 3 ) {
+               FG_LOG( FG_CLIPPER, FG_ALERT, 
+                       "Polygon with less than 3 data points." );
+               exit(-1);
+           }
+
+           in >> startx;
+           in >> starty;
+           v_list.vertex[0].x = startx;
+           v_list.vertex[0].y = starty;
+           FG_LOG( FG_CLIPPER, FG_BULK, "0 = " 
+                   << startx << ", " << starty );
+
+           for ( j = 1; j < count - 1; ++j ) {
+               in >> x;
+               in >> y;
+               v_list.vertex[j].x = x;
+               v_list.vertex[j].y = y;
+               FG_LOG( FG_CLIPPER, FG_BULK, j << " = " << x << ", " << y );
+           }
+           v_list.num_vertices = count - 1;
+
+           in >> lastx;
+           in >> lasty;
+
+           if ( (fabs(startx - lastx) < FG_EPSILON) 
+                && (fabs(starty - lasty) < FG_EPSILON) ) {
+               // last point same as first, discard
+           } else {
+               v_list.vertex[count - 1].x = lastx;
+               v_list.vertex[count - 1].y = lasty;
+               ++v_list.num_vertices;
+               FG_LOG( FG_CLIPPER, FG_BULK, count - 1 << " = " 
+                       << lastx << ", " << lasty );
+           }
+
+           gpc_polygon *poly = new gpc_polygon;
+           poly->num_contours = 0;
+           poly->contour = NULL;
+           gpc_add_contour( poly, &v_list );
+
+           int area = (int)poly_type;
+           if ( area < FG_MAX_AREAS ) {
+               polys_in.polys[area].push_back(poly);
+           } else {
+               FG_LOG( FG_CLIPPER, FG_ALERT, "Polygon type out of range = " 
+                       << poly_type);
+               exit(-1);
+           }
+       }
+
+       in >> skipcomment;
+    }
+
+    // FILE *ofp= fopen("outfile", "w");
+    // gpc_write_polygon(ofp, &polys.landuse);
+
+    return true;
+}
+
+
+// Do actually clipping work
+bool fgClipperMaster(const point2d& min, const point2d& max) {
+    gpc_polygon accum, result_diff, result_union, tmp;
+    polylist_iterator current, last;
+
+    FG_LOG( FG_CLIPPER, FG_INFO, "Running master clipper" );
+
+    accum.num_contours = 0;
+
+    cout << "  (" << min.x << "," << min.y << ") (" 
+        << max.x << "," << max.y << ")" << endl;
+
+    // set up clipping tile
+    v_list.vertex[0].x = min.x;
+    v_list.vertex[0].y = min.y;
+
+    v_list.vertex[1].x = max.x;
+    v_list.vertex[1].y = min.y;
+
+    v_list.vertex[2].x = max.x;
+    v_list.vertex[2].y = max.y;
+
+    v_list.vertex[3].x = min.x;
+    v_list.vertex[3].y = max.y;
+
+    v_list.num_vertices = 4;
+
+    polys_in.safety_base.num_contours = 0;
+    polys_in.safety_base.contour = NULL;
+    gpc_add_contour( &polys_in.safety_base, &v_list );
+
+    // process polygons in priority order
+    for ( int i = 0; i < FG_MAX_AREAS; ++i ) {
+
+       current = polys_in.polys[i].begin();
+       last = polys_in.polys[i].end();
+       for ( ; current != last; ++current ) {
+           FG_LOG( FG_CLIPPER, FG_DEBUG, get_area_name( (AreaType)i ) 
+                   << " = " << (*current)->contour->num_vertices );
+
+#ifdef EXTRA_SAFETY_CLIP
+           // clip to base tile
+           gpc_polygon_clip(GPC_INT, &polys_in.safety_base, *current, &tmp);
+#else
+           &tmp = *current;
+#endif
+
+           // clip current polygon against previous higher priority
+           // stuff
+           if ( accum.num_contours == 0 ) {
+               result_diff = tmp;
+               result_union = tmp;
+           } else {
+               gpc_polygon_clip(GPC_DIFF, &accum, &tmp, &result_diff);
+               gpc_polygon_clip(GPC_UNION, &accum, &tmp, &result_union);
+           }
+           
+           polys_out.polys[i].push_back(&result_diff);
+           accum = result_union;
+       }
+    }
+
+    // finally, what ever is left over goes to base terrain
+
+    // clip to accum against original base tile
+    gpc_polygon_clip(GPC_DIFF, &polys_in.safety_base, &accum, 
+                    &polys_out.safety_base);
+
+    // tmp output accum
+    FILE *ofp= fopen("accum", "w");
+    gpc_write_polygon(ofp, &accum);
+
+    // tmp output safety_base
+    ofp= fopen("safety_base", "w");
+    gpc_write_polygon(ofp, &polys_out.safety_base);
+
+    return true;
+}
+
+
+// $Log$
+// Revision 1.1  1999/03/01 15:39:39  curt
+// Initial revision.
+//
diff --git a/Clipper/clipper.hxx b/Clipper/clipper.hxx
new file mode 100644 (file)
index 0000000..79b7e16
--- /dev/null
@@ -0,0 +1,87 @@
+// clipper.hxx -- top level routines to take a series of arbitrary areas and
+//                produce a tight fitting puzzle pieces that combine to make a
+//                tile
+//
+// Written by Curtis Olson, started February 1999.
+//
+// Copyright (C) 1999  Curtis L. Olson  - curt@flightgear.org
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+// (Log is kept at end of this file)
+
+
+#ifndef _CLIPPER_HXX
+#define _CLIPPER_HXX
+
+
+#ifndef __cplusplus                                                          
+# error This library requires C++
+#endif                                   
+
+
+#include <Include/compiler.h>
+
+
+// include Generic Polygon Clipping Library
+//
+//    http://www.cs.man.ac.uk/aig/staff/alan/software/
+//
+extern "C" {
+#include <gpc.h>
+}
+
+#include STL_STRING
+#include <vector>
+
+typedef vector < gpc_polygon * > polylist;
+typedef polylist::iterator polylist_iterator;
+
+#define FG_MAX_AREAS 20
+
+class point2d {
+public:
+    double x, y;
+};
+
+
+class FGPolyList {
+public:
+    polylist polys[FG_MAX_AREAS];
+    gpc_polygon safety_base;
+};
+
+
+// Initialize Clipper (allocate and/or connect structures)
+bool fgClipperInit();
+
+
+// Load a polygon definition file
+bool fgClipperLoadPolygons(const string& path);
+
+
+// Do actually clipping work
+bool fgClipperMaster(const point2d& min, const point2d& max);
+
+
+#endif // _CLIPPER_HXX
+
+
+// $Log$
+// Revision 1.1  1999/03/01 15:39:39  curt
+// Initial revision.
+//
diff --git a/Clipper/main.cxx b/Clipper/main.cxx
new file mode 100644 (file)
index 0000000..4aa613a
--- /dev/null
@@ -0,0 +1,114 @@
+// main.cxx -- sample use of the clipper lib
+//
+// Written by Curtis Olson, started February 1999.
+//
+// Copyright (C) 1999  Curtis L. Olson  - curt@flightgear.org
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+// (Log is kept at end of this file)
+
+
+#include "clipper.hxx"
+
+#include <Debug/logstream.hxx>
+#include <Bucket/newbucket.hxx>
+
+
+int main( int argc, char **argv ) {
+    point2d global_min, global_max;
+
+    fglog().setLogLevels( FG_ALL, FG_DEBUG );
+
+    global_min.x = global_min.y = 200;
+    global_max.y = global_max.x = -200;
+
+    fgClipperInit();
+
+    if ( argc < 2 ) {
+       FG_LOG( FG_CLIPPER, FG_ALERT, "Usage: " << argv[0] 
+               << " file1 file2 ..." );
+       exit(-1);
+    }
+
+    // process all specified polygon files
+    for ( int i = 1; i < argc; i++ ) {
+       string full_path = argv[i];
+
+       // determine bucket for this polygon
+       int pos = full_path.rfind("/");
+       string file_name = full_path.substr(pos + 1);
+       cout << "file name = " << file_name << endl;
+
+       pos = file_name.find(".");
+       string base_name = file_name.substr(0, pos);
+       cout << "base_name = " << base_name << endl;
+
+       long int index;
+       sscanf( base_name.c_str(), "%ld", &index);
+       FGBucket b(index);
+       cout << "bucket = " << b << endl;
+
+       // calculate bucket dimensions
+       point2d c, min, max;
+
+       c.x = b.get_center_lon();
+       c.y = b.get_center_lat();
+       double span = bucket_span(c.y);
+
+       if ( (c.y >= -89.0) && (c.y < 89.0) ) {
+           min.x = c.x - span / 2.0;
+           max.x = c.x + span / 2.0;
+           min.y = c.y - FG_HALF_BUCKET_SPAN;
+           max.y = c.y + FG_HALF_BUCKET_SPAN;
+       } else if ( c.y < -89.0) {
+           min.x = -90.0;
+           max.x = -89.0;
+           min.y = -180.0;
+           max.y = 180.0;
+       } else if ( c.y >= 89.0) {
+           min.x = 89.0;
+           max.x = 90.0;
+           min.y = -180.0;
+           max.y = 180.0;
+       } else {
+           FG_LOG ( FG_GENERAL, FG_ALERT, 
+                    "Out of range latitude in clip_and_write_poly() = " 
+                    << c.y );
+       }
+
+       if ( min.x < global_min.x ) global_min.x = min.x;
+       if ( min.y < global_min.y ) global_min.y = min.y;
+       if ( max.x > global_max.x ) global_max.x = max.x;
+       if ( max.y > global_max.y ) global_max.y = max.y;
+
+       // finally, load the polygon(s) from this file
+       fgClipperLoadPolygons( full_path );
+    }
+
+    // do the clipping
+    fgClipperMaster(global_min, global_max);
+
+    FG_LOG( FG_CLIPPER, FG_INFO, "finished main" );
+
+    return 0;
+}
+
+// $Log$
+// Revision 1.1  1999/03/01 15:39:39  curt
+// Initial revision.
+//