|
@@ -243,15 +243,21 @@ inline bool doubleEq(double a, double b) { return fabs(a - b) < EPSILON; }
|
243
|
243
|
// _____________________________________________________________________________
|
244
|
244
|
template <typename T>
|
245
|
245
|
inline bool contains(const Point<T>& p, const Box<T>& box) {
|
246
|
|
- return p.getX() >= box.getLowerLeft().getX() &&
|
247
|
|
- p.getX() <= box.getUpperRight().getX() &&
|
248
|
|
- p.getY() >= box.getLowerLeft().getY() &&
|
249
|
|
- p.getY() <= box.getUpperRight().getY();
|
|
246
|
+ // check if point lies in box
|
|
247
|
+ return (fabs(p.getX() - box.getLowerLeft().getX()) < EPSILON ||
|
|
248
|
+ p.getX() > box.getLowerLeft().getX()) &&
|
|
249
|
+ (fabs(p.getX() - box.getUpperRight().getX()) < EPSILON ||
|
|
250
|
+ p.getX() < box.getUpperRight().getX()) &&
|
|
251
|
+ (fabs(p.getY() - box.getLowerLeft().getY()) < EPSILON ||
|
|
252
|
+ p.getY() > box.getLowerLeft().getY()) &&
|
|
253
|
+ (fabs(p.getY() - box.getUpperRight().getY()) < EPSILON ||
|
|
254
|
+ p.getY() < box.getUpperRight().getY());
|
250
|
255
|
}
|
251
|
256
|
|
252
|
257
|
// _____________________________________________________________________________
|
253
|
258
|
template <typename T>
|
254
|
259
|
inline bool contains(const Line<T>& l, const Box<T>& box) {
|
|
260
|
+ // check if line lies in box
|
255
|
261
|
for (const auto& p : l)
|
256
|
262
|
if (!contains(p, box)) return false;
|
257
|
263
|
return true;
|
|
@@ -260,24 +266,35 @@ inline bool contains(const Line<T>& l, const Box<T>& box) {
|
260
|
266
|
// _____________________________________________________________________________
|
261
|
267
|
template <typename T>
|
262
|
268
|
inline bool contains(const LineSegment<T>& l, const Box<T>& box) {
|
|
269
|
+ // check if line segment lies in box
|
263
|
270
|
return contains(l.first, box) && contains(l.second, box);
|
264
|
271
|
}
|
265
|
272
|
|
266
|
273
|
// _____________________________________________________________________________
|
267
|
274
|
template <typename T>
|
268
|
275
|
inline bool contains(const Box<T>& b, const Box<T>& box) {
|
|
276
|
+ // check if box b lies in box
|
269
|
277
|
return contains(b.getLowerLeft(), box) && contains(b.getUpperRight(), box);
|
270
|
278
|
}
|
271
|
279
|
|
272
|
280
|
// _____________________________________________________________________________
|
273
|
281
|
template <typename T>
|
274
|
282
|
inline bool contains(const Point<T>& p, const LineSegment<T>& ls) {
|
|
283
|
+ // check if point p lies in (on) line segment ls
|
275
|
284
|
return fabs(crossProd(p, ls)) < EPSILON && contains(p, getBoundingBox(ls));
|
276
|
285
|
}
|
277
|
286
|
|
278
|
287
|
// _____________________________________________________________________________
|
279
|
288
|
template <typename T>
|
|
289
|
+inline bool contains(const LineSegment<T>& a, const LineSegment<T>& b) {
|
|
290
|
+ // check if line segment a is contained in line segment b
|
|
291
|
+ return contains(a.first, b) && contains(a.second, b);
|
|
292
|
+}
|
|
293
|
+
|
|
294
|
+// _____________________________________________________________________________
|
|
295
|
+template <typename T>
|
280
|
296
|
inline bool contains(const Point<T>& p, const Line<T>& l) {
|
|
297
|
+ // check if point p lies in line l
|
281
|
298
|
for (size_t i = 1; i < l.size(); i++) {
|
282
|
299
|
if (contains(p, LineSegment<T>(l[i - 1], l[i]))) return true;
|
283
|
300
|
}
|
|
@@ -287,6 +304,8 @@ inline bool contains(const Point<T>& p, const Line<T>& l) {
|
287
|
304
|
// _____________________________________________________________________________
|
288
|
305
|
template <typename T>
|
289
|
306
|
inline bool contains(const Point<T>& p, const Polygon<T>& poly) {
|
|
307
|
+ // check if point p lies in polygon
|
|
308
|
+
|
290
|
309
|
// see https://de.wikipedia.org/wiki/Punkt-in-Polygon-Test_nach_Jordan
|
291
|
310
|
int8_t c = -1;
|
292
|
311
|
|
|
@@ -328,19 +347,53 @@ inline int8_t polyContCheck(const Point<T>& a, Point<T> b, Point<T> c) {
|
328
|
347
|
// _____________________________________________________________________________
|
329
|
348
|
template <typename T>
|
330
|
349
|
inline bool contains(const Polygon<T>& polyC, const Polygon<T>& poly) {
|
331
|
|
- for (const auto& p : polyC.getOuter()) {
|
332
|
|
- if (!contains(p, poly)) {
|
|
350
|
+ // check if polygon polyC lies in polygon poly
|
|
351
|
+
|
|
352
|
+ for (size_t i = 1; i < polyC.getOuter().size(); i++) {
|
|
353
|
+ if (!contains(LineSegment<T>(polyC.getOuter()[i - 1], polyC.getOuter()[i]),
|
|
354
|
+ poly))
|
|
355
|
+ return false;
|
|
356
|
+ }
|
|
357
|
+
|
|
358
|
+ // also check the last hop
|
|
359
|
+ if (!contains(LineSegment<T>(polyC.getOuter().back(), polyC.getOuter().front()),
|
|
360
|
+ poly))
|
|
361
|
+ return false;
|
|
362
|
+
|
|
363
|
+ return true;
|
|
364
|
+}
|
|
365
|
+
|
|
366
|
+// _____________________________________________________________________________
|
|
367
|
+template <typename T>
|
|
368
|
+inline bool contains(const LineSegment<T>& ls, const Polygon<T>& p) {
|
|
369
|
+ // check if linesegment ls lies in polygon poly
|
|
370
|
+
|
|
371
|
+ // if one of the endpoints lies outside, abort
|
|
372
|
+ if (!contains(ls.first, p)) return false;
|
|
373
|
+ if (!contains(ls.second, p)) return false;
|
|
374
|
+
|
|
375
|
+ for (size_t i = 1; i < p.getOuter().size(); i++) {
|
|
376
|
+ auto seg = LineSegment<T>(p.getOuter()[i - 1], p.getOuter()[i]);
|
|
377
|
+ if (!(contains(ls.first, seg) || contains(ls.second, seg)) &&
|
|
378
|
+ intersects(seg, ls)) {
|
333
|
379
|
return false;
|
334
|
380
|
}
|
335
|
381
|
}
|
|
382
|
+
|
|
383
|
+ auto seg = LineSegment<T>(p.getOuter().back(), p.getOuter().front());
|
|
384
|
+ if (!(contains(ls.first, seg) || contains(ls.second, seg)) &&
|
|
385
|
+ intersects(seg, ls)) {
|
|
386
|
+ return false;
|
|
387
|
+ }
|
|
388
|
+
|
336
|
389
|
return true;
|
337
|
390
|
}
|
338
|
391
|
|
339
|
392
|
// _____________________________________________________________________________
|
340
|
393
|
template <typename T>
|
341
|
394
|
inline bool contains(const Line<T>& l, const Polygon<T>& poly) {
|
342
|
|
- for (const auto& p : l) {
|
343
|
|
- if (!contains(p, poly)) {
|
|
395
|
+ for (size_t i = 1; i < l.size(); i++) {
|
|
396
|
+ if (!contains(LineSegment<T>(l[i - 1], l[i]), poly)) {
|
344
|
397
|
return false;
|
345
|
398
|
}
|
346
|
399
|
}
|
|
@@ -351,9 +404,7 @@ inline bool contains(const Line<T>& l, const Polygon<T>& poly) {
|
351
|
404
|
template <typename T>
|
352
|
405
|
inline bool contains(const Line<T>& l, const Line<T>& other) {
|
353
|
406
|
for (const auto& p : l) {
|
354
|
|
- if (!contains(p, other)) {
|
355
|
|
- return false;
|
356
|
|
- }
|
|
407
|
+ if (!contains(p, other)) return false;
|
357
|
408
|
}
|
358
|
409
|
return true;
|
359
|
410
|
}
|
|
@@ -361,17 +412,13 @@ inline bool contains(const Line<T>& l, const Line<T>& other) {
|
361
|
412
|
// _____________________________________________________________________________
|
362
|
413
|
template <typename T>
|
363
|
414
|
inline bool contains(const Box<T>& b, const Polygon<T>& poly) {
|
364
|
|
- return contains(b.getLowerLeft(), poly) &&
|
365
|
|
- contains(b.getUpperRight(), poly) &&
|
366
|
|
- contains(Point<T>(b.getUpperRight().getX(), b.getLowerLeft().getY()),
|
367
|
|
- poly) &&
|
368
|
|
- contains(Point<T>(b.getLowerLeft().getX(), b.getUpperRight().getY()),
|
369
|
|
- poly);
|
|
415
|
+ return contains(convexHull(b), poly);
|
370
|
416
|
}
|
371
|
417
|
|
372
|
418
|
// _____________________________________________________________________________
|
373
|
419
|
template <typename T>
|
374
|
420
|
inline bool contains(const Polygon<T>& poly, const Box<T>& b) {
|
|
421
|
+ // check of poly lies in box
|
375
|
422
|
for (const auto& p : poly.getOuter()) {
|
376
|
423
|
if (!contains(p, b)) return false;
|
377
|
424
|
}
|
|
@@ -400,6 +447,8 @@ inline bool contains(const std::vector<GeometryA<T>>& multigeo,
|
400
|
447
|
// _____________________________________________________________________________
|
401
|
448
|
template <typename T>
|
402
|
449
|
inline bool intersects(const LineSegment<T>& ls1, const LineSegment<T>& ls2) {
|
|
450
|
+ // check if two linesegments intersect
|
|
451
|
+
|
403
|
452
|
// two line segments intersect of there is a single, well-defined intersection
|
404
|
453
|
// point between them. If more than 1 endpoint is colinear with any line,
|
405
|
454
|
// the segments have infinite intersections. We handle this case as non-
|
|
@@ -470,6 +519,39 @@ inline bool intersects(const Box<T>& b1, const Box<T>& b2) {
|
470
|
519
|
|
471
|
520
|
// _____________________________________________________________________________
|
472
|
521
|
template <typename T>
|
|
522
|
+inline bool intersects(const Box<T>& b, const Polygon<T>& poly) {
|
|
523
|
+ return intersects(b, poly);
|
|
524
|
+}
|
|
525
|
+
|
|
526
|
+// _____________________________________________________________________________
|
|
527
|
+template <typename T>
|
|
528
|
+inline bool intersects(const Polygon<T>& poly, const Box<T>& b) {
|
|
529
|
+ if (intersects(
|
|
530
|
+ LineSegment<T>(b.getLowerLeft(), Point<T>(b.getUpperRight().getX(),
|
|
531
|
+ b.getLowerLeft().getY())),
|
|
532
|
+ poly))
|
|
533
|
+ return true;
|
|
534
|
+ if (intersects(
|
|
535
|
+ LineSegment<T>(b.getLowerLeft(), Point<T>(b.getLowerLeft().getX(),
|
|
536
|
+ b.getUpperRight().getY())),
|
|
537
|
+ poly))
|
|
538
|
+ return true;
|
|
539
|
+ if (intersects(
|
|
540
|
+ LineSegment<T>(b.getUpperRight(), Point<T>(b.getLowerLeft().getX(),
|
|
541
|
+ b.getUpperRight().getY())),
|
|
542
|
+ poly))
|
|
543
|
+ return true;
|
|
544
|
+ if (intersects(
|
|
545
|
+ LineSegment<T>(b.getUpperRight(), Point<T>(b.getUpperRight().getX(),
|
|
546
|
+ b.getLowerLeft().getY())),
|
|
547
|
+ poly))
|
|
548
|
+ return true;
|
|
549
|
+
|
|
550
|
+ return contains(poly, b) || contains(b, poly);
|
|
551
|
+}
|
|
552
|
+
|
|
553
|
+// _____________________________________________________________________________
|
|
554
|
+template <typename T>
|
473
|
555
|
inline bool intersects(const LineSegment<T>& ls, const Box<T>& b) {
|
474
|
556
|
if (intersects(ls, LineSegment<T>(b.getLowerLeft(),
|
475
|
557
|
Point<T>(b.getUpperRight().getX(),
|
|
@@ -499,6 +581,7 @@ inline bool intersects(const LineSegment<T>& ls, const Polygon<T>& p) {
|
499
|
581
|
return true;
|
500
|
582
|
}
|
501
|
583
|
|
|
584
|
+ // also check the last hop
|
502
|
585
|
if (intersects(LineSegment<T>(p.getOuter().back(), p.getOuter().front()), ls))
|
503
|
586
|
return true;
|
504
|
587
|
|