Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/geom/Polygon2D.java @ 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 | |
children | fe7f9264a2ed |
line wrap: on
line source
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 :