changeset 1794:2ad7ba85a2b3

Work in progress: Added polygon to help creating 'Raum/Flaeche' renderers. flys-artifacts/trunk@3117 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 28 Oct 2011 16:59:03 +0000
parents 1636686070f7
children fe7f9264a2ed
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/geom/Polygon2D.java
diffstat 2 files changed, 176 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Fri Oct 28 14:42:24 2011 +0000
+++ b/flys-artifacts/ChangeLog	Fri Oct 28 16:59:03 2011 +0000
@@ -1,3 +1,9 @@
+2011-10-28	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/geom/Polygon2D.java: New.
+	  Polygon class to help creating "Raum/Flaeche" renderers with gaps in
+	  their definitions. WORK IN PROGRESS!
+
 2011-10-28  Ingo Weinzierl <ingo@intevation.de>
 
 	* doc/conf/themes.xml: Added a default theme for the riveraxis used in the
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/geom/Polygon2D.java	Fri Oct 28 16:59:03 2011 +0000
@@ -0,0 +1,170 @@
+package de.intevation.flys.geom;
+
+import gnu.trove.TDoubleArrayList;
+
+import java.io.Serializable;
+
+import java.awt.Shape;
+
+import java.awt.geom.Path2D;
+import java.awt.geom.Point2D;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Collections;
+
+public class Polygon2D
+implements   Serializable
+{
+    public static final Comparator<Point2D> POINT_X_CMP =
+        new Comparator<Point2D>() {
+            public int compare(Point2D a, Point2D b) {
+                double d = a.getX() - b.getX();
+                if (d < 0d) return -1;
+                return d > 0d ? + 1 : 0;
+            }
+        };
+
+    public static final Comparator<Point2D []> FIRST_POINT_X =
+        new Comparator<Point2D []>() {
+            public int compare(Point2D [] a, Point2D [] b) {
+                if (a.length == 0) return -1; // should not happen.
+                if (b.length == 0) return +1; // should not happen.
+                double d = a[0].getX() - b[0].getX();
+                if (d < 0d) return -1;
+                return d > 0d ? + 1 : 0;
+            }
+        };
+
+    protected TDoubleArrayList xs;
+    protected TDoubleArrayList ys;
+
+    public Polygon2D() {
+        xs = new TDoubleArrayList();
+        ys = new TDoubleArrayList();
+    }
+
+    public void add(double x, double y) {
+        xs.add(x);
+        ys.add(y);
+    }
+
+    public double area() {
+        double area = 0d;
+
+		for (int i = 0, N = xs.size(); i < N; ++i) {
+			int j = (i + 1) % N;
+			area += xs.getQuick(i)*ys.getQuick(j);
+			area -= xs.getQuick(j)*ys.getQuick(i);
+		}
+
+        return 0.5d*area;
+    }
+
+    public Shape toShape() {
+        Path2D.Double path = new Path2D.Double();
+
+        int N = xs.size();
+
+        if (N > 0) {
+            path.moveTo(xs.getQuick(0), ys.getQuick(0));
+            for (int i = 1; i < N; ++i) {
+                path.lineTo(xs.getQuick(i), ys.getQuick(i));
+            }
+            path.closePath();
+        }
+
+        return path;
+    }
+
+    protected static List<Point2D []> splitByNaNs(
+        double [] xs,
+        double [] ys
+    ) {
+        List<Point2D []> parts = new ArrayList<Point2D []>();
+
+        List<Point2D> tmp = new ArrayList<Point2D>(xs.length);
+
+        for (int i = 0; i < xs.length; ++i) {
+            double x = xs[i];
+            double y = ys[i];
+
+            if (Double.isNaN(x) || Double.isNaN(y)) {
+                if (!tmp.isEmpty()) {
+                    Point2D [] part = new Point2D[tmp.size()];
+                    parts.add(tmp.toArray(part));
+                    tmp.clear();
+                }
+            }
+            else {
+                tmp.add(new Point2D.Double(x, y));
+            }
+        }
+
+        if (!tmp.isEmpty()) {
+            Point2D [] part = new Point2D[tmp.size()];
+            parts.add(tmp.toArray(part));
+        }
+
+        return parts;
+    }
+
+    public static void createPolygons(
+        double [] xAs, double [] yAs,
+        double [] xBs, double [] yBs,
+        List<Polygon2D> positives,
+        List<Polygon2D> negatives
+    ) {
+        if (xAs.length == 0 || xBs.length == 0) {
+            return;
+        }
+
+        List<Point2D []> splAs = splitByNaNs(xAs, yAs);
+        List<Point2D []> splBs = splitByNaNs(xBs, yBs);
+
+        // They feeded us with NaNs only.
+        if (splAs.isEmpty() || splBs.isEmpty()) {
+            return;
+        }
+
+        // Sort each part by x to ensure that the first
+        // is the smallest.
+        for (Point2D [] splA: splAs) {
+            Arrays.sort(splA, POINT_X_CMP);
+        }
+
+        for (Point2D [] splB: splBs) {
+            Arrays.sort(splB, POINT_X_CMP);
+        }
+
+        // Now sort all parts by there first elements.
+        // Should be good enough to find overlapping regions.
+        Collections.sort(splAs, FIRST_POINT_X);
+        Collections.sort(splBs, FIRST_POINT_X);
+
+        // Check if the two series intersect at all.
+        // If no then there will be no area between them.
+
+        Point2D [] p1 = splAs.get(0);
+        Point2D [] p2 = splBs.get(splBs.size()-1);
+
+        // First of As greater than last of Bs.
+        if (POINT_X_CMP.compare(p1[0], p2[p2.length-1]) > 0) {
+            return;
+        }
+
+        p2 = splAs.get(splAs.size()-1);
+        p1 = splBs.get(0);
+
+        //  First of Bs greater than last of As.
+        if (POINT_X_CMP.compare(p1[0], p2[p2.length-1]) > 0) {
+            return;
+        }
+
+        // TODO: Intersect/split the two series parts.
+
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org