comparison 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
comparison
equal deleted inserted replaced
1798:552888e9c64a 1799:281b9430c720
13 import java.util.Comparator; 13 import java.util.Comparator;
14 import java.util.Collections; 14 import java.util.Collections;
15 15
16 import de.intevation.flys.artifacts.math.Linear; 16 import de.intevation.flys.artifacts.math.Linear;
17 17
18 import static de.intevation.flys.geom.VectorUtils.X;
19 import static de.intevation.flys.geom.VectorUtils.Y;
20 import static de.intevation.flys.geom.VectorUtils.EPSILON;
21
18 public class Polygon2D 22 public class Polygon2D
19 implements Serializable 23 implements Serializable
20 { 24 {
21 private static final double X(Point2D p) {
22 return p.getX();
23 }
24
25 private static final double Y(Point2D p) {
26 return p.getY();
27 }
28
29 public static final Comparator<Point2D> POINT_X_CMP = 25 public static final Comparator<Point2D> POINT_X_CMP =
30 new Comparator<Point2D>() { 26 new Comparator<Point2D>() {
31 public int compare(Point2D a, Point2D b) { 27 public int compare(Point2D a, Point2D b) {
32 double d = X(a) - X(b); 28 double d = X(a) - X(b);
33 if (d < 0d) return -1; 29 if (d < 0d) return -1;
48 44
49 protected List<Point2D> points; 45 protected List<Point2D> points;
50 46
51 public Polygon2D() { 47 public Polygon2D() {
52 points = new ArrayList<Point2D>(); 48 points = new ArrayList<Point2D>();
49 }
50
51 public Point2D(List<Point2D> points) {
52 this.points = points;
53 } 53 }
54 54
55 public void add(double x, double y) { 55 public void add(double x, double y) {
56 points.add(new Point2D.Double(x, y)); 56 points.add(new Point2D.Double(x, y));
57 } 57 }
195 List<Point2D> bpoints = new ArrayList<Point2D>(); 195 List<Point2D> bpoints = new ArrayList<Point2D>();
196 196
197 double ax = X(as[0]); 197 double ax = X(as[0]);
198 double bx = X(bs[0]); 198 double bx = X(bs[0]);
199 199
200 int ai = 0; 200 int ai = 1;
201 int bi = 0; 201 int bi = 1;
202
203 boolean intersect = false;
202 204
203 if (ax == bx) { 205 if (ax == bx) {
204 apoints.add(as[0]); 206 apoints.add(as[0]);
205 bpoints.add(bs[0]); 207 bpoints.add(bs[0]);
206 } 208 }
207 else if (ax > bx) { 209 else if (ax > bx) {
208 apoints.add(as[0]); 210 apoints.add(as[0]);
209 bi = 1; // exists because of overlap
210 double bx1; 211 double bx1;
211 while ((bx1 = X(bs[bi])) < ax) ++bi; 212 while ((bx1 = X(bs[bi])) < ax) ++bi;
212 if (bx1 == ax) { 213 if (bx1 == ax) {
213 bpoints.add(bs[bi]); 214 bpoints.add(bs[bi]);
214 } 215 }
215 else { // need to calculate start b point. 216 else { // need to calculate start b point.
217 intersect = true;
216 double by1 = Linear.linear( 218 double by1 = Linear.linear(
217 ax, 219 ax,
218 X(bs[bi-1]), bx1, 220 X(bs[bi-1]), bx1,
219 Y(bs[bi-1]), Y(bs[bi])); 221 Y(bs[bi-1]), Y(bs[bi]));
220 222
221 bpoints.add(new Point2D.Double(ax, by1)); 223 bpoints.add(new Point2D.Double(ax, by1));
222 } 224 }
223 } 225 }
224 else { // bx > ax: Symmetric case 226 else { // bx > ax: Symmetric case
225 bpoints.add(bs[0]); 227 bpoints.add(bs[0]);
226 ai = 1; // exists because of overlap
227 double ax1; 228 double ax1;
228 while ((ax1 = X(as[ai])) < bx) ++ai; 229 while ((ax1 = X(as[ai])) < bx) ++ai;
229 if (ax1 == bx) { 230 if (ax1 == bx) {
230 apoints.add(as[ai]); 231 apoints.add(as[ai]);
231 } 232 }
232 else { // need to calculate start b point. 233 else { // need to calculate start b point.
234 intersect = true;
233 double ay1 = Linear.linear( 235 double ay1 = Linear.linear(
234 bx, 236 bx,
235 X(as[ai-1]), ax1, 237 X(as[ai-1]), ax1,
236 Y(as[ai-1]), Y(as[ai])); 238 Y(as[ai-1]), Y(as[ai]));
237 239
240 } 242 }
241 243
242 // now we have a point in each list, decide if neg/pos. 244 // now we have a point in each list, decide if neg/pos.
243 boolean neg = Y(bpoints.get(0)) > Y(apoints.get(0)); 245 boolean neg = Y(bpoints.get(0)) > Y(apoints.get(0));
244 246
245 // TODO: Continue with inner points 247 // Continue with inner points
248
249 Line line = new Line();
250
251 while (ai < as.length && bi < bs.length) {
252 double xan = X(as[ai]);
253 double xbn = X(bs[bi]);
254 if (xan == xbn) {
255 double yan = Y(as[ai]);
256 double ybn = Y(bs[ai]);
257
258 if (neg) {
259 if (yan > ybn) { // intersection
260 // TODO: calculate intersection point
261 // finish polygon and start a new one
262 }
263 else { // no intersection
264 addCheck(as[ai], apoints);
265 addCheck(bs[bi], bpoints);
266 ++ai;
267 ++bi;
268 }
269 }
270 else { // not neg
271 if (ybn > yan) { // intersection
272 // TODO: calculate intersection point
273 // finish polygon and start a new one
274 }
275 else { // no intersection
276 addCheck(as[ai], apoints);
277 addCheck(bs[bi], bpoints);
278 ++ai;
279 ++bi;
280 }
281 }
282 }
283 else if (xan > xbn) {
284 line.set(apoints.get(apoints.size()-1), as[ai]);
285 double dir = neg ? -1d: 1d; // XXX: correct sign?
286 while (bi < bs.length
287 && X(bs[bi]) < xan
288 && line.eval(bs[bi])*dir > EPSILON)
289 ++bi;
290 if (bi == bs.length) {
291 // b run out of points
292 // calculate Y(last_a, as[ai]) for X(bs[bi-1])
293 double ay1 = Linear.linear(
294 X(bs[bi-1]),
295 X(apoints.get(apoints.size()-1)), X(as[ai]),
296 Y(apoints.get(apoints.size()-1)), Y(as[ai]));
297 addCheck(new Point2D.Double(X(bs[bi-1]), ay1), apoints);
298 addCheck(bs[bi-1], bpoints);
299 break;
300 }
301 else {
302 // TODO: intersect line and/or X(bs[bi]) >= xan?
303 }
304 }
305 else { // xbn > xan
306 line.set(bpoints.get(bpoints.size()-1), bs[bi]);
307 // TODO: continue symmetric
308 }
309 }
310
311 // TODO: Continue with closing segment
312 }
313
314 public static final class Line {
315
316 private double a;
317 private double b;
318 private double c;
319
320 public Line() {
321 }
322
323 public Line(Point2D p1, Point2D p2) {
324 set(p1, p2);
325 }
326
327 public void set(Point2D p1, Point2D p2) {
328 Point2D p3 =
329 VectorUtils.normalize(
330 VectorUtils.sub(p1, p2));
331
332 Point2D n = VectorUtils.ortho(p3);
333
334 a = X(n);
335 b = Y(n);
336
337 // a*x + b*y + c = 0
338 // c = -a*x -b*y
339
340 c = -a*X(p1) - b*Y(p1);
341 }
342
343 public double eval(Point2D p) {
344 return a*X(p) + b*Y(p) + c;
345 }
246 } 346 }
247 347
248 public static void createPolygons( 348 public static void createPolygons(
249 double [] xAs, double [] yAs, 349 double [] xAs, double [] yAs,
250 double [] xBs, double [] yBs, 350 double [] xBs, double [] yBs,

http://dive4elements.wald.intevation.org