From 966b911e1f51aebc5efa15c2aadbb090f75aad14 Mon Sep 17 00:00:00 2001 From: Erica Fischer Date: Wed, 8 Nov 2023 14:55:27 -0800 Subject: [PATCH] Setting up for scanline --- polygon.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/polygon.cpp b/polygon.cpp index 3e82866ff..5194625b4 100644 --- a/polygon.cpp +++ b/polygon.cpp @@ -9,6 +9,55 @@ struct point { } }; +typedef std::pair segment; + +struct scan_transition { + double y; + size_t segment; + + scan_transition(double y_, size_t segment_) + : y(y_), segment(segment_) { + } + + bool operator<(scan_transition const &s) const { + if (y < s.y) { + return true; + } else { + return false; + } + } +}; + +std::vector snap_round(std::vector segs) { + bool again = true; + + while (again) { + again = false; + + // set up for a scanline traversal of the segments + // to find the pairs that intersect + // while not looking at pairs that can't possibly intersect + + std::vector tops; + std::vector bottoms; + + for (size_t i = 0; i < segs.size(); i++) { + if (segs[i].first.y < segs[i].second.y) { + tops.emplace_back(segs[i].first.y, i); + bottoms.emplace_back(segs[i].second.y, i); + } else { + tops.emplace_back(segs[i].second.y, i); + bottoms.emplace_back(segs[i].first.y, i); + } + } + + std::sort(tops.begin(), tops.end()); + std::sort(bottoms.begin(), bottoms.end()); + } + + return segs; +} + drawvec clean_polygon(drawvec const &geom, int z, int detail) { double scale = 1LL << (-(32 - detail - z)); @@ -40,6 +89,8 @@ drawvec clean_polygon(drawvec const &geom, int z, int detail) { // snap-round intersecting segments + segments = snap_round(segments); + // remove duplicate segments with opposite windings // reassemble segments into rings