more work on util
This commit is contained in:
parent
223ffa6f6b
commit
3af004e49b
4 changed files with 139 additions and 3 deletions
|
@ -38,6 +38,20 @@ class Box {
|
||||||
Point<T> _ll, _ur;
|
Point<T> _ll, _ur;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class RotatedBox {
|
||||||
|
public:
|
||||||
|
RotatedBox() : _box() {}
|
||||||
|
RotatedBox(const Box<T>& box) : _box(box), _deg(0), _center() {}
|
||||||
|
RotatedBox(const Point<T>& ll, const Point<T>& ur) : _box(ll, ur), _deg(0), _center() {}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
Box<T> _box;
|
||||||
|
double _deg;
|
||||||
|
Point<T> _center;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace geo
|
} // namespace geo
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "util/Misc.h"
|
#include "util/Misc.h"
|
||||||
#include "util/geo/Box.h"
|
#include "util/geo/Box.h"
|
||||||
|
@ -215,6 +216,90 @@ inline bool contains(const Point<T>& p, const Line<T>& l) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
template <typename T>
|
||||||
|
inline bool contains(const Point<T>& p, const Polygon<T>& poly) {
|
||||||
|
// see https://de.wikipedia.org/wiki/Punkt-in-Polygon-Test_nach_Jordan
|
||||||
|
int8_t c = -1;
|
||||||
|
|
||||||
|
for (size_t i = 1; i < poly.getOuter().size(); i++) {
|
||||||
|
c *= polyContCheck(p, poly.getOuter()[i - 1], poly.getOuter()[i]);
|
||||||
|
if (c == 0) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
c *= polyContCheck(p, poly.getOuter().back(), poly.getOuter()[0]);
|
||||||
|
|
||||||
|
return c >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
template <typename T>
|
||||||
|
inline int8_t polyContCheck(const Point<T>& a, Point<T> b, Point<T> c) {
|
||||||
|
if (a.getY() == b.getY() && a.getY() == c.getY())
|
||||||
|
return (!((b.getX() <= a.getX() && a.getX() <= c.getX()) ||
|
||||||
|
(c.getX() <= a.getX() && a.getX() <= b.getX())));
|
||||||
|
if (a.getY() == b.getY() && a.getX() == b.getX()) return 0;
|
||||||
|
if (b.getY() > c.getY()) {
|
||||||
|
Point<T> tmp = b;
|
||||||
|
b = c;
|
||||||
|
c = tmp;
|
||||||
|
}
|
||||||
|
if (a.getY() <= b.getY() || a.getY() > c.getY()) return 1;
|
||||||
|
|
||||||
|
double d = (b.getX() - a.getX()) * (c.getY() - a.getY()) -
|
||||||
|
(b.getY() - a.getY()) * (c.getX() - a.getX());
|
||||||
|
if (d > 0) return -1;
|
||||||
|
if (d < 0) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
template <typename T>
|
||||||
|
inline bool contains(const Polygon<T>& polyC, const Polygon<T>& poly) {
|
||||||
|
for (const auto& p : polyC.getOuter()) {
|
||||||
|
if (!contains(p, poly)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
template <typename T>
|
||||||
|
inline bool contains(const Line<T>& l, const Polygon<T>& poly) {
|
||||||
|
for (const auto& p : l) {
|
||||||
|
if (!contains(p, poly)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
template <typename T>
|
||||||
|
inline bool contains(const Box<T>& b, const Polygon<T>& poly) {
|
||||||
|
return contains(b.getLowerLeft(), poly) &&
|
||||||
|
contains(b.getUpperRight(), poly) &&
|
||||||
|
contains(Point<T>(b.getUpperRight().getX(), b.getLowerLeft().getY()),
|
||||||
|
poly) &&
|
||||||
|
contains(Point<T>(b.getLowerLeft().getX(), b.getUpperRight().getY()),
|
||||||
|
poly);
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
template <typename T>
|
||||||
|
inline bool contains(const Polygon<T>& poly, const Box<T>& b) {
|
||||||
|
for (const auto& p : poly.getOuter()) {
|
||||||
|
if (!contains(p, b)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
template <typename T>
|
||||||
|
inline bool contains(const Polygon<T>& poly, const Line<T>& l) {
|
||||||
|
for (const auto& p : poly.getOuter()) {
|
||||||
|
if (!contains(p, l)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// _____________________________________________________________________________
|
// _____________________________________________________________________________
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool intersects(const LineSegment<T>& ls1, const LineSegment<T>& ls2) {
|
inline bool intersects(const LineSegment<T>& ls1, const LineSegment<T>& ls2) {
|
||||||
|
@ -439,8 +524,7 @@ inline double innerProd(double x1, double y1, double x2, double y2, double x3,
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline double innerProd(const Point<T>& a, const Point<T>& b,
|
inline double innerProd(const Point<T>& a, const Point<T>& b,
|
||||||
const Point<T>& c) {
|
const Point<T>& c) {
|
||||||
return innerProd(a.template getX(), a.template getY(), b.template getX(),
|
return innerProd(a.getX(), a.getY(), b.getX(), b.getY(), c.getX(), c.getY());
|
||||||
b.template getY(), c.template getX(), c.template getY());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// _____________________________________________________________________________
|
// _____________________________________________________________________________
|
||||||
|
@ -486,6 +570,12 @@ inline std::string getWKT(const Line<T>& l) {
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
template <typename T>
|
||||||
|
inline std::string getWKT(const LineSegment<T>& l) {
|
||||||
|
return getWKT(Line<T>{l.first, l.second});
|
||||||
|
}
|
||||||
|
|
||||||
// _____________________________________________________________________________
|
// _____________________________________________________________________________
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline std::string getWKT(const Box<T>& l) {
|
inline std::string getWKT(const Box<T>& l) {
|
||||||
|
@ -744,6 +834,14 @@ inline Box<T> getBoundingBox(const Line<T>& l) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _____________________________________________________________________________
|
||||||
|
template <typename T>
|
||||||
|
inline Box<T> getBoundingBox(const Polygon<T>& pol) {
|
||||||
|
Box<T> ret;
|
||||||
|
for (const auto& p : pol.getOuter()) ret = extendBox(p, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// _____________________________________________________________________________
|
// _____________________________________________________________________________
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline Box<T> getBoundingBox(const LineSegment<T>& ls) {
|
inline Box<T> getBoundingBox(const LineSegment<T>& ls) {
|
||||||
|
|
|
@ -15,7 +15,8 @@ namespace geo {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Polygon {
|
class Polygon {
|
||||||
public:
|
public:
|
||||||
// maximum inverse box as default value of box
|
Polygon() {}
|
||||||
|
|
||||||
Polygon(const Line<T>& l) : _outer(l) {}
|
Polygon(const Line<T>& l) : _outer(l) {}
|
||||||
|
|
||||||
const std::vector<Point<T>>& getOuter() const { return _outer; }
|
const std::vector<Point<T>>& getOuter() const { return _outer; }
|
||||||
|
|
|
@ -942,6 +942,29 @@ CASE("geometry") {
|
||||||
EXPECT(geo::intersects(Box<double>(Point<double>(0, 0), Point<double>(3, 3)), boxa));
|
EXPECT(geo::intersects(Box<double>(Point<double>(0, 0), Point<double>(3, 3)), boxa));
|
||||||
EXPECT(geo::intersects(Box<double>(Point<double>(1.5, 1.5), Point<double>(3, 3)), boxa));
|
EXPECT(geo::intersects(Box<double>(Point<double>(1.5, 1.5), Point<double>(3, 3)), boxa));
|
||||||
EXPECT(geo::intersects(Box<double>(Point<double>(0, 0), Point<double>(1.5, 1.5)), boxa));
|
EXPECT(geo::intersects(Box<double>(Point<double>(0, 0), Point<double>(1.5, 1.5)), boxa));
|
||||||
|
|
||||||
|
Polygon<double> poly({Point<double>(1, 1), Point<double>(3, 2), Point<double>(4, 3), Point<double>(6, 3), Point<double>(5, 1)});
|
||||||
|
EXPECT(geo::getWKT(poly) == "POLYGON ((1 1, 3 2, 4 3, 6 3, 5 1))");
|
||||||
|
EXPECT(geo::contains(Point<double>(4, 2), poly));
|
||||||
|
EXPECT(!geo::contains(Point<double>(3, 3), poly));
|
||||||
|
EXPECT(geo::contains(Point<double>(1, 1), poly));
|
||||||
|
EXPECT(geo::contains(Point<double>(3, 2), poly));
|
||||||
|
EXPECT(geo::contains(Point<double>(4, 3), poly));
|
||||||
|
EXPECT(geo::contains(Point<double>(6, 3), poly));
|
||||||
|
EXPECT(geo::contains(Point<double>(5, 1), poly));
|
||||||
|
|
||||||
|
EXPECT(geo::contains(Line<double>{Point<double>(6, 3), Point<double>(5, 1)}, poly));
|
||||||
|
EXPECT(!geo::contains(Line<double>{Point<double>(6, 3), Point<double>(50, 1)}, poly));
|
||||||
|
EXPECT(geo::contains(Line<double>{Point<double>(4, 2), Point<double>(4.5, 2)}, poly));
|
||||||
|
EXPECT(geo::contains(Line<double>{Point<double>(4, 2), Point<double>(5, 1)}, poly));
|
||||||
|
|
||||||
|
Box<double> polybox(Point<double>(1, 1), Point<double>(6, 4));
|
||||||
|
EXPECT(geo::contains(poly, polybox));
|
||||||
|
EXPECT(!geo::contains(polybox, poly));
|
||||||
|
Box<double> polybox2(Point<double>(4, 1), Point<double>(5, 2));
|
||||||
|
EXPECT(geo::contains(polybox2, poly));
|
||||||
|
EXPECT(geo::contains(poly, getBoundingBox(poly)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue