Mercurial > dive4elements > river
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 :