be a bit less verbose

This commit is contained in:
Patrick Brosi 2018-07-24 19:33:18 +02:00
parent 45027d5496
commit 7f0443243c
12 changed files with 210 additions and 45 deletions

View file

@ -403,6 +403,14 @@ inline bool intersects(const LineSegment<T>& ls1, const LineSegment<T>& ls2) {
((crossProd(ls2.first, ls1) < 0) ^ (crossProd(ls2.second, ls1) < 0)));
}
// _____________________________________________________________________________
template <typename T>
inline bool intersects(const Point<T>& a, const Point<T>& b, const Point<T>& c,
const Point<T>& d) {
// legacy function
return intersects(LineSegment<T>(a, b), LineSegment<T>(c, d));
}
// _____________________________________________________________________________
template <typename T>
inline bool intersects(const Line<T>& ls1, const Line<T>& ls2) {
@ -605,6 +613,78 @@ inline double dist(double x1, double y1, double x2, double y2) {
return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
// _____________________________________________________________________________
template <typename T>
inline double dist(const LineSegment<T>& ls, const Point<T>& p) {
return distToSegment(ls, p);
}
// _____________________________________________________________________________
template <typename T>
inline double dist(const Point<T>& p, const LineSegment<T>& ls) {
return dist(ls, p);
}
// _____________________________________________________________________________
template <typename T>
inline double dist(const LineSegment<T>& ls1, const LineSegment<T>& ls2) {
if (intersects(ls1, ls2)) return 0;
double d1 = dist(ls1.first, ls2);
double d2 = dist(ls1.second, ls2);
double d3 = dist(ls2.first, ls1);
double d4 = dist(ls2.second, ls1);
return std::min(d1, std::min(d2, (std::min(d3, d4))));
}
// _____________________________________________________________________________
template <typename T>
inline double dist(const Point<T>& p, const Line<T>& l) {
double d = std::numeric_limits<double>::infinity();
for (size_t i = 1; i < l.size(); i++) {
double dTmp = distToSegment(l[i-1], l[i], p);
if (dTmp < EPSILON) return 0;
if (dTmp < d) d = dTmp;
}
return d;
}
// _____________________________________________________________________________
template <typename T>
inline double dist(const Line<T>& l, const Point<T>& p) {
return dist(p, l);
}
// _____________________________________________________________________________
template <typename T>
inline double dist(const LineSegment<T>& ls, const Line<T>& l) {
double d = std::numeric_limits<double>::infinity();
for (size_t i = 1; i < l.size(); i++) {
double dTmp = dist(ls, LineSegment<T>(l[i-1], l[i]));
if (dTmp < EPSILON) return 0;
if (dTmp < d) d = dTmp;
}
return d;
}
// _____________________________________________________________________________
template <typename T>
inline double dist(const Line<T>& l, const LineSegment<T>& ls) {
return dist(ls, l);
}
// _____________________________________________________________________________
template <typename T>
inline double dist(const Line<T>& la, const Line<T>& lb) {
double d = std::numeric_limits<double>::infinity();
for (size_t i = 1; i < la.size(); i++) {
double dTmp = dist(LineSegment<T>(la[i-1], la[i]), lb);
if (dTmp < EPSILON) return 0;
if (dTmp < d) d = dTmp;
}
return d;
}
// _____________________________________________________________________________
inline double innerProd(double x1, double y1, double x2, double y2, double x3,
double y3) {

View file

@ -33,7 +33,7 @@ class Polygon {
};
template <typename T>
using MultiPolyon = std::vector<Polygon<T>>;
using MultiPolygon = std::vector<Polygon<T>>;
} // namespace geo
} // namespace util

View file

@ -1024,7 +1024,7 @@ CASE("geometry") {
EXPECT(geo::dist(geo::centroid(Polygon<double>({{0, 0}, {3, 4}, {4,3}})), Point<double>(7.0/3.0,7.0/3.0)) == approx(0));
auto polyy = Polygon<double>({{0, 0}, {3, 4}, {4,3}});
MultiPolyon<double> mpoly{polyy, polyy};
MultiPolygon<double> mpoly{polyy, polyy};
EXPECT(geo::getWKT(polyy) == "POLYGON ((0 0, 3 4, 4 3, 0 0))");
EXPECT(geo::getWKT(mpoly) == "MULTIPOLYGON (((0 0, 3 4, 4 3, 0 0)), ((0 0, 3 4, 4 3, 0 0)))");
@ -1209,6 +1209,23 @@ CASE("geometry") {
auto obox = geo::getOrientedEnvelope(geo::Line<double>{{0, 0}, {1, 1}, {1.5, 0.5}});
EXPECT(geo::contains(geo::convexHull(obox), geo::Polygon<double>({{0.0, 0.0}, {1.0, 1.0}, {1.5, 0.5}, {0.5, -0.5}})));
EXPECT(geo::contains(geo::Polygon<double>({{0.0, 0.0}, {1.0, 1.0}, {1.5, 0.5}, {0.5, -0.5}}), geo::convexHull(obox)));
EXPECT(geo::dist(geo::LineSegment<double>{{1, 1}, {3, 1}}, geo::LineSegment<double>{{2, 2}, {2, 0}}) == approx(0));
EXPECT(geo::dist(geo::LineSegment<double>{{1, 1}, {3, 1}}, geo::LineSegment<double>{{2, 4}, {2, 2}}) == approx(1));
EXPECT(geo::dist(geo::LineSegment<double>{{1, 1}, {3, 1}}, geo::LineSegment<double>{{1, 1}, {3, 1}}) == approx(0));
EXPECT(geo::dist(geo::LineSegment<double>{{1, 1}, {3, 1}}, geo::LineSegment<double>{{1, 2}, {3, 2}}) == approx(1));
EXPECT(geo::dist(geo::LineSegment<double>{{1, 1}, {3, 1}}, geo::LineSegment<double>{{1, 2}, {3, 5}}) == approx(1));
EXPECT(geo::dist(geo::Line<double>{{1, 1}, {3, 1}}, geo::Point<double>{2, 1}) == approx(0));
EXPECT(geo::dist(geo::Line<double>{{1, 1}, {3, 1}}, geo::Point<double>{2, 2}) == approx(1));
EXPECT(geo::dist(geo::Line<double>{{1, 1}, {3, 1}}, geo::Point<double>{3, 1}) == approx(0));
EXPECT(geo::dist(geo::Line<double>{{1, 1}, {3, 1}}, geo::Point<double>{1, 1}) == approx(0));
EXPECT(geo::dist(Line<double>{{7, 7}, {7, -7}, {-7, -7}, {-7, 7}, {9, 0}, {-9, 0}, {0, 9}, {0, -9}}, Line<double>{{7, 7}, {7, -7}, {-7, -7}, {-7, 7}, {9, 0}, {-9, 0}, {0, 9}, {0, -9}}) == approx(0));
EXPECT(geo::dist(Line<double>{{7, 7}, {7, -7}, {-7, -7}, {-7, 7}, {9, 0}, {-9, 0}, {0, 9}, {0, -9}}, LineSegment<double>{{6, 7}, {8, -7}}) == approx(0));
EXPECT(geo::dist(Line<double>{{7, 7}, {7, -7}, {-7, -7}, {-7, 7}, {9, 0}, {-9, 0}, {0, 9}, {0, -9}}, Point<double>{7, 4}) == approx(0));
EXPECT(geo::dist(Line<double>{{0, 0}, {1, 1}, {2, 0}}, Line<double>{{1.5, 0.5}, {1.5, 100}}) == approx(0));
EXPECT(geo::dist(Line<double>{{0, 0}, {1, 1}, {2, 0}}, Line<double>{{2, 0.5}, {2, 100}}) == approx(0.353553));
}
}};