From 14e43cbfd34ec1b9aa57ddb2a28047ad908ee3e6 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Wed, 25 Oct 2023 14:19:58 -0700 Subject: [PATCH] Oops, never checked this in --- earcut.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 earcut.cpp diff --git a/earcut.cpp b/earcut.cpp new file mode 100644 index 00000000..d24eda3a --- /dev/null +++ b/earcut.cpp @@ -0,0 +1,91 @@ +#include "geometry.hpp" +#include "mapbox/geometry/earcut.hpp" + +using Coord = long long; +using N = size_t; +using Point = std::array; + +drawvec fix_by_triangulation(drawvec const &dv, int z, int detail) { + std::vector> polygon; + drawvec out; + double scale = 1LL << (32 - z - detail); + + for (size_t i = 0; i < dv.size(); i++) { + if (dv[i].op == VT_MOVETO) { + size_t j; + for (j = i + 1; j < dv.size(); j++) { + if (dv[j].op != VT_LINETO) { + break; + } + } + + std::vector ring; + // j - 1 because earcut docs indicate that it doesn't expect + // a duplicate last point in each ring + for (size_t k = i; k < j - 1; k++) { + Point p = {(long long) dv[k].x, (long long) dv[k].y}; + ring.push_back(p); + out.push_back(dv[k]); + } + polygon.push_back(ring); + + i = j - 1; + } + } + + std::vector indices = mapbox::earcut(polygon); + + bool again = true; + while (again) { + again = false; + for (size_t i = 0; i + 2 < indices.size(); i += 3) { + for (size_t j = 0; j < 3; j++) { + size_t v1 = i + j; + size_t v2 = i + ((j + 1) % 3); + + if (std::llround(out[indices[v1]].x / scale) == std::llround(out[indices[v2]].x / scale) && + std::llround(out[indices[v1]].y / scale) == std::llround(out[indices[v2]].y / scale)) { + double ang = atan2(out[indices[v2]].y - out[indices[v1]].y, out[indices[v2]].x - out[indices[v1]].x); + + printf("at %zu/%zu: %zu and %zu: ", i, j, v1, v2); + printf("z%d: was %f,%f to %f,%f ", + z, + out[indices[v1]].x / scale, out[indices[v1]].y / scale, + out[indices[v2]].x / scale, out[indices[v2]].y / scale); + + out[indices[v1]].x -= scale * cos(ang) * sqrt(2); + out[indices[v1]].y -= scale * sin(ang) * sqrt(2); + out[indices[v2]].x += scale * cos(ang) * sqrt(2); + out[indices[v2]].y += scale * sin(ang) * sqrt(2); + again = true; + + printf("now %f,%f to %f,%f\n", + out[indices[v1]].x / scale, out[indices[v1]].y / scale, + out[indices[v2]].x / scale, out[indices[v2]].y / scale); + } + } + } + } + + drawvec out2; + for (size_t i = 0; i < out.size(); i++) { + if (out[i].op == VT_MOVETO) { + size_t j; + for (j = i + 1; j < out.size(); j++) { + if (out[j].op != VT_LINETO) { + break; + } + } + + for (size_t k = i; k < j; k++) { + out2.push_back(out[k]); + } + + // re-close the ring + out2.push_back(draw(VT_LINETO, out[i].x, out[i].y)); + i = j - 1; + } + } + + return out2; +}