comparison 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
comparison
equal deleted inserted replaced
1793:1636686070f7 1794:2ad7ba85a2b3
1 package de.intevation.flys.geom;
2
3 import gnu.trove.TDoubleArrayList;
4
5 import java.io.Serializable;
6
7 import java.awt.Shape;
8
9 import java.awt.geom.Path2D;
10 import java.awt.geom.Point2D;
11
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.Arrays;
15 import java.util.Comparator;
16 import java.util.Collections;
17
18 public class Polygon2D
19 implements Serializable
20 {
21 public static final Comparator<Point2D> POINT_X_CMP =
22 new Comparator<Point2D>() {
23 public int compare(Point2D a, Point2D b) {
24 double d = a.getX() - b.getX();
25 if (d < 0d) return -1;
26 return d > 0d ? + 1 : 0;
27 }
28 };
29
30 public static final Comparator<Point2D []> FIRST_POINT_X =
31 new Comparator<Point2D []>() {
32 public int compare(Point2D [] a, Point2D [] b) {
33 if (a.length == 0) return -1; // should not happen.
34 if (b.length == 0) return +1; // should not happen.
35 double d = a[0].getX() - b[0].getX();
36 if (d < 0d) return -1;
37 return d > 0d ? + 1 : 0;
38 }
39 };
40
41 protected TDoubleArrayList xs;
42 protected TDoubleArrayList ys;
43
44 public Polygon2D() {
45 xs = new TDoubleArrayList();
46 ys = new TDoubleArrayList();
47 }
48
49 public void add(double x, double y) {
50 xs.add(x);
51 ys.add(y);
52 }
53
54 public double area() {
55 double area = 0d;
56
57 for (int i = 0, N = xs.size(); i < N; ++i) {
58 int j = (i + 1) % N;
59 area += xs.getQuick(i)*ys.getQuick(j);
60 area -= xs.getQuick(j)*ys.getQuick(i);
61 }
62
63 return 0.5d*area;
64 }
65
66 public Shape toShape() {
67 Path2D.Double path = new Path2D.Double();
68
69 int N = xs.size();
70
71 if (N > 0) {
72 path.moveTo(xs.getQuick(0), ys.getQuick(0));
73 for (int i = 1; i < N; ++i) {
74 path.lineTo(xs.getQuick(i), ys.getQuick(i));
75 }
76 path.closePath();
77 }
78
79 return path;
80 }
81
82 protected static List<Point2D []> splitByNaNs(
83 double [] xs,
84 double [] ys
85 ) {
86 List<Point2D []> parts = new ArrayList<Point2D []>();
87
88 List<Point2D> tmp = new ArrayList<Point2D>(xs.length);
89
90 for (int i = 0; i < xs.length; ++i) {
91 double x = xs[i];
92 double y = ys[i];
93
94 if (Double.isNaN(x) || Double.isNaN(y)) {
95 if (!tmp.isEmpty()) {
96 Point2D [] part = new Point2D[tmp.size()];
97 parts.add(tmp.toArray(part));
98 tmp.clear();
99 }
100 }
101 else {
102 tmp.add(new Point2D.Double(x, y));
103 }
104 }
105
106 if (!tmp.isEmpty()) {
107 Point2D [] part = new Point2D[tmp.size()];
108 parts.add(tmp.toArray(part));
109 }
110
111 return parts;
112 }
113
114 public static void createPolygons(
115 double [] xAs, double [] yAs,
116 double [] xBs, double [] yBs,
117 List<Polygon2D> positives,
118 List<Polygon2D> negatives
119 ) {
120 if (xAs.length == 0 || xBs.length == 0) {
121 return;
122 }
123
124 List<Point2D []> splAs = splitByNaNs(xAs, yAs);
125 List<Point2D []> splBs = splitByNaNs(xBs, yBs);
126
127 // They feeded us with NaNs only.
128 if (splAs.isEmpty() || splBs.isEmpty()) {
129 return;
130 }
131
132 // Sort each part by x to ensure that the first
133 // is the smallest.
134 for (Point2D [] splA: splAs) {
135 Arrays.sort(splA, POINT_X_CMP);
136 }
137
138 for (Point2D [] splB: splBs) {
139 Arrays.sort(splB, POINT_X_CMP);
140 }
141
142 // Now sort all parts by there first elements.
143 // Should be good enough to find overlapping regions.
144 Collections.sort(splAs, FIRST_POINT_X);
145 Collections.sort(splBs, FIRST_POINT_X);
146
147 // Check if the two series intersect at all.
148 // If no then there will be no area between them.
149
150 Point2D [] p1 = splAs.get(0);
151 Point2D [] p2 = splBs.get(splBs.size()-1);
152
153 // First of As greater than last of Bs.
154 if (POINT_X_CMP.compare(p1[0], p2[p2.length-1]) > 0) {
155 return;
156 }
157
158 p2 = splAs.get(splAs.size()-1);
159 p1 = splBs.get(0);
160
161 // First of Bs greater than last of As.
162 if (POINT_X_CMP.compare(p1[0], p2[p2.length-1]) > 0) {
163 return;
164 }
165
166 // TODO: Intersect/split the two series parts.
167
168 }
169 }
170 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org