From 9ae1e575cad53a2075885f5ab1ba1ed9dcc69e66 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Wed, 6 Dec 2023 16:56:52 -0800 Subject: [PATCH] By George, I think she's got it! --- earcut.cpp | 48 +++++++++++++++++++++--------------------------- geometry.cpp | 23 +++++++++++++++++++++++ geometry.hpp | 1 + tile.cpp | 7 ++++++- 4 files changed, 51 insertions(+), 28 deletions(-) diff --git a/earcut.cpp b/earcut.cpp index cf8d8e60..43cfb3c1 100644 --- a/earcut.cpp +++ b/earcut.cpp @@ -17,35 +17,28 @@ drawvec reinforce(drawvec const &pts, std::vector> polygon, d size_t v2 = i + ((j + 1) % 3); size_t v3 = i + ((j + 2) % 3); - double px, py; - - if (distance_from_line(pts[indices[v1]].x, pts[indices[v1]].y, // the point - pts[indices[v2]].x, pts[indices[v2]].y, // start of opposite side - pts[indices[v3]].x, pts[indices[v3]].y, // end of opposite side - &px, &py) < 2 * scale) { - double ang = atan2(pts[indices[v1]].y - py, pts[indices[v1]].x - px); - - // make a new triangle that is not so flat - out2.push_back(draw(VT_MOVETO, pts[indices[v2]].x, pts[indices[v2]].y)); - out2.push_back(draw(VT_LINETO, pts[indices[v3]].x, pts[indices[v3]].y)); - out2.push_back(draw(VT_LINETO, px + scale * 2 * cos(ang), py + scale * 2 * sin(ang))); - out2.push_back(draw(VT_LINETO, pts[indices[v2]].x, pts[indices[v2]].y)); - } - #if 0 - long long dx = pts[indices[v2]].x - pts[indices[v1]].x; - long long dy = pts[indices[v2]].y - pts[indices[v1]].y; - double d = sqrt(dx * dx + dy * dy); - if (d < sqrt(2) * scale) { - // make a new triangle with a longer side - double ang = atan2(dy, dx); - - out2.push_back(draw(VT_MOVETO, pts[indices[v3]].x, pts[indices[v3]].y)); - out2.push_back(draw(VT_LINETO, pts[indices[v1]].x - sqrt(2) * scale * cos(ang), pts[indices[v1]].y - sqrt(2) * scale * sin(ang))); - out2.push_back(draw(VT_LINETO, pts[indices[v2]].x + sqrt(2) * scale * cos(ang), pts[indices[v2]].y + sqrt(2) * scale * sin(ang))); - out2.push_back(draw(VT_LINETO, pts[indices[v3]].x, pts[indices[v3]].y)); - } + out2.push_back(draw(VT_MOVETO, pts[indices[v1]].x, pts[indices[v1]].y)); + out2.push_back(draw(VT_LINETO, pts[indices[v2]].x, pts[indices[v2]].y)); + out2.push_back(draw(VT_LINETO, pts[indices[v3]].x, pts[indices[v3]].y)); + out2.push_back(draw(VT_LINETO, pts[indices[v1]].x, pts[indices[v1]].y)); #endif + + double px, py; + double d = distance_from_line_noclamp(pts[indices[v1]].x, pts[indices[v1]].y, + pts[indices[v2]].x, pts[indices[v2]].y, + pts[indices[v3]].x, pts[indices[v3]].y, + &px, &py); + + if (d < scale) { + double ang = atan2(py - pts[indices[v1]].y, px - pts[indices[v1]].x); + double dist = scale - d; + + out2.push_back(draw(VT_MOVETO, pts[indices[v1]].x, pts[indices[v1]].y)); + out2.push_back(draw(VT_LINETO, pts[indices[v2]].x + dist * cos(ang), pts[indices[v2]].y + dist * sin(ang))); + out2.push_back(draw(VT_LINETO, pts[indices[v3]].x + dist * cos(ang), pts[indices[v3]].y + dist * sin(ang))); + out2.push_back(draw(VT_LINETO, pts[indices[v1]].x, pts[indices[v1]].y)); + } } } @@ -95,6 +88,7 @@ drawvec fix_by_triangulation(drawvec const &dv, int z, int detail) { for (auto const &d : additional) { out2.push_back(d); } + for (auto const &d : dv) { out2.push_back(d); } diff --git a/geometry.cpp b/geometry.cpp index b754e258..57cf4630 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -380,6 +380,29 @@ double distance_from_line(long long point_x, long long point_y, long long segA_x return out; } +double distance_from_line_noclamp(long long point_x, long long point_y, long long segA_x, long long segA_y, long long segB_x, long long segB_y, double *px, double *py) { + long long p2x = segB_x - segA_x; + long long p2y = segB_y - segA_y; + double something = p2x * p2x + p2y * p2y; + double u = (0 == something) ? 0 : ((point_x - segA_x) * p2x + (point_y - segA_y) * p2y) / (something); + + double x = segA_x + u * p2x; + double y = segA_y + u * p2y; + + if (px != NULL) { + *px = std::round(x); + } + if (py != NULL) { + *py = std::round(y); + } + + double dx = x - point_x; + double dy = y - point_y; + + double out = std::round(sqrt(dx * dx + dy * dy) * 16.0) / 16.0; + return out; +} + // https://github.com/Project-OSRM/osrm-backend/blob/733d1384a40f/Algorithms/DouglasePeucker.cpp static void douglas_peucker(drawvec &geom, int start, int n, double e, size_t kept, size_t retain) { std::stack recursion_stack; diff --git a/geometry.hpp b/geometry.hpp index 7caf9dea..5e13187a 100644 --- a/geometry.hpp +++ b/geometry.hpp @@ -97,6 +97,7 @@ drawvec clip_point(drawvec &geom, long long x1, long long y1, long long x2, long void visvalingam(drawvec &ls, size_t start, size_t end, double threshold, size_t retain); int pnpoly(const drawvec &vert, size_t start, size_t nvert, long long testx, long long testy); double distance_from_line(long long point_x, long long point_y, long long segA_x, long long segA_y, long long segB_x, long long segB_y, double *px, double *py); +double distance_from_line_noclamp(long long point_x, long long point_y, long long segA_x, long long segA_y, long long segB_x, long long segB_y, double *px, double *py); std::string overzoom(mvt_tile tile, int oz, int ox, int oy, int nz, int nx, int ny, int detail, int buffer, std::set const &keep, bool do_compress, diff --git a/tile.cpp b/tile.cpp index f9f74e6b..867d2ead 100644 --- a/tile.cpp +++ b/tile.cpp @@ -614,11 +614,16 @@ void *partial_feature_worker(void *v) { drawvec geom = (*partials)[i].geoms[0]; if (t == VT_POLYGON) { + geom = remove_noop(geom, VT_POLYGON, 0); drawvec cleaned = clean_or_clip_poly(geom, 0, 0, false, false); - drawvec fixed = fix_by_triangulation(geom, z, out_detail); + drawvec fixed = fix_by_triangulation(cleaned, z, out_detail); + geom = clean_or_clip_poly(fixed, 0, 0, false, false); +#if 0 if (fixed != cleaned) { geom = fixed; } + (*partials)[i].t = t = VT_LINE; +#endif } to_tile_scale(geom, z, out_detail);