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