diff flys-artifacts/src/main/java/de/intevation/flys/artifacts/geom/Polygon2D.java @ 1799:281b9430c720

Polygon2D: More code to build polygons from curve. flys-artifacts/trunk@3123 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 31 Oct 2011 15:54:02 +0000
parents 552888e9c64a
children 1402991208d5
line wrap: on
line diff
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/geom/Polygon2D.java	Mon Oct 31 11:32:11 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/geom/Polygon2D.java	Mon Oct 31 15:54:02 2011 +0000
@@ -15,17 +15,13 @@
 
 import de.intevation.flys.artifacts.math.Linear;
 
+import static de.intevation.flys.geom.VectorUtils.X;
+import static de.intevation.flys.geom.VectorUtils.Y;
+import static de.intevation.flys.geom.VectorUtils.EPSILON;
+
 public class Polygon2D
 implements   Serializable
 {
-    private static final double X(Point2D p) {
-        return p.getX();
-    }
-
-    private static final double Y(Point2D p) {
-        return p.getY();
-    }
-
     public static final Comparator<Point2D> POINT_X_CMP =
         new Comparator<Point2D>() {
             public int compare(Point2D a, Point2D b) {
@@ -52,6 +48,10 @@
         points = new ArrayList<Point2D>();
     }
 
+    public Point2D(List<Point2D> points) {
+        this.points = points;
+    }
+
     public void add(double x, double y) {
         points.add(new Point2D.Double(x, y));
     }
@@ -197,8 +197,10 @@
         double ax = X(as[0]);
         double bx = X(bs[0]);
 
-        int ai = 0;
-        int bi = 0;
+        int ai = 1;
+        int bi = 1;
+
+        boolean intersect = false;
 
         if (ax == bx) {
             apoints.add(as[0]);
@@ -206,13 +208,13 @@
         }
         else if (ax > bx) {
             apoints.add(as[0]);
-            bi = 1; // exists because of overlap
             double bx1;
             while ((bx1 = X(bs[bi])) < ax) ++bi;
             if (bx1 == ax) {
                 bpoints.add(bs[bi]);
             }
             else { // need to calculate start b point.
+                intersect = true;
                 double by1 = Linear.linear(
                     ax,
                     X(bs[bi-1]), bx1,
@@ -223,13 +225,13 @@
         }
         else { // bx > ax: Symmetric case
             bpoints.add(bs[0]);
-            ai = 1; // exists because of overlap
             double ax1;
             while ((ax1 = X(as[ai])) < bx) ++ai;
             if (ax1 == bx) {
                 apoints.add(as[ai]);
             }
             else { // need to calculate start b point.
+                intersect = true;
                 double ay1 = Linear.linear(
                     bx,
                     X(as[ai-1]), ax1,
@@ -242,7 +244,105 @@
         // now we have a point in each list, decide if neg/pos.
         boolean neg = Y(bpoints.get(0)) > Y(apoints.get(0));
 
-        // TODO: Continue with inner points
+        // Continue with inner points
+
+        Line line = new Line();
+
+        while (ai < as.length && bi < bs.length) {
+            double xan = X(as[ai]);
+            double xbn = X(bs[bi]);
+            if (xan == xbn) { 
+                double yan = Y(as[ai]);
+                double ybn = Y(bs[ai]);
+
+                if (neg) {
+                    if (yan > ybn) { // intersection
+                        // TODO: calculate intersection point
+                        // finish polygon and start a new one
+                    }
+                    else { // no intersection
+                        addCheck(as[ai], apoints);
+                        addCheck(bs[bi], bpoints);
+                        ++ai;
+                        ++bi;
+                    }
+                }
+                else { // not neg
+                    if (ybn > yan) { // intersection
+                        // TODO: calculate intersection point
+                        // finish polygon and start a new one
+                    }
+                    else { // no intersection
+                        addCheck(as[ai], apoints);
+                        addCheck(bs[bi], bpoints);
+                        ++ai;
+                        ++bi;
+                    }
+                }
+            }
+            else if (xan > xbn) {
+                line.set(apoints.get(apoints.size()-1), as[ai]);
+                double dir = neg ? -1d: 1d; // XXX: correct sign?
+                while  (bi < bs.length 
+                    && X(bs[bi]) < xan
+                    && line.eval(bs[bi])*dir > EPSILON) 
+                    ++bi;
+                if (bi == bs.length) {
+                    // b run out of points
+                    // calculate Y(last_a, as[ai]) for X(bs[bi-1])
+                    double ay1 = Linear.linear(
+                        X(bs[bi-1]),
+                        X(apoints.get(apoints.size()-1)), X(as[ai]),
+                        Y(apoints.get(apoints.size()-1)), Y(as[ai]));
+                    addCheck(new Point2D.Double(X(bs[bi-1]), ay1), apoints);
+                    addCheck(bs[bi-1], bpoints);
+                    break;
+                }
+                else {
+                    // TODO: intersect line and/or X(bs[bi]) >= xan?
+                }
+            }
+            else { // xbn > xan
+                line.set(bpoints.get(bpoints.size()-1), bs[bi]);
+                // TODO: continue symmetric
+            }
+        }
+
+        // TODO: Continue with closing segment
+    }
+
+    public static final class Line {
+
+        private double a;
+        private double b;
+        private double c;
+
+        public Line() {
+        }
+
+        public Line(Point2D p1, Point2D p2) {
+            set(p1, p2);
+        }
+
+        public void set(Point2D p1, Point2D p2) {
+            Point2D p3 = 
+                VectorUtils.normalize(
+                VectorUtils.sub(p1, p2));
+
+            Point2D n = VectorUtils.ortho(p3);
+
+            a = X(n);
+            b = Y(n);
+
+            // a*x + b*y + c = 0
+            // c = -a*x -b*y
+
+            c = -a*X(p1) - b*Y(p1);
+        }
+
+        public double eval(Point2D p) {
+            return a*X(p) + b*Y(p) + c;
+        }
     }
 
     public static void createPolygons(

http://dive4elements.wald.intevation.org