Doing the scan line through the segments

This commit is contained in:
Erica Fischer
2023-11-08 15:44:01 -08:00
parent 966b911e1f
commit 6bebc1b427
3 changed files with 60 additions and 6 deletions
+53 -6
View File
@@ -1,3 +1,4 @@
#include <stdio.h>
#include "geometry.hpp"
struct point {
@@ -11,6 +12,10 @@ struct point {
typedef std::pair<point, point> segment;
bool intersect(std::vector<segment> &segs, size_t s1, size_t s2) {
return false;
}
struct scan_transition {
double y;
size_t segment;
@@ -38,21 +43,63 @@ std::vector<segment> snap_round(std::vector<segment> segs) {
// to find the pairs that intersect
// while not looking at pairs that can't possibly intersect
// index by rounded y coordinates, since we will be
// intersecting with rounded coordinates
std::vector<scan_transition> tops;
std::vector<scan_transition> 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);
if (std::round(segs[i].first.y) < std::round(segs[i].second.y)) {
tops.emplace_back(std::round(segs[i].first.y), i);
bottoms.emplace_back(std::round(segs[i].second.y), i);
} else {
tops.emplace_back(segs[i].second.y, i);
bottoms.emplace_back(segs[i].first.y, i);
tops.emplace_back(std::round(segs[i].second.y), i);
bottoms.emplace_back(std::round(segs[i].first.y), i);
}
}
std::sort(tops.begin(), tops.end());
std::sort(bottoms.begin(), bottoms.end());
// do the scan
std::set<size_t> active;
size_t bottom = 0;
for (size_t i = 0; i < tops.size(); i++) {
// activate anything that is coming into view
active.insert(tops[i].segment);
if (i + 1 < tops.size() && tops[i + 1].y == tops[i].y) {
continue;
}
// look at the active segments
for (size_t s1 : active) {
for (size_t s2 : active) {
if (s1 < s2) {
if (intersect(segs, s1, s2)) {
// if the segments intersected,
// we need to do another scan,
// because introducing a new node
// may have caused new intersections
again = true;
}
}
}
}
// deactivate anything that is going out of view
if (i + 1 < tops.size()) {
while (bottom < bottoms.size() && bottoms[bottom].y < tops[i + 1].y) {
auto found = active.find(bottoms[bottom].segment);
active.erase(found);
bottom++;
}
}
}
}
return segs;
@@ -70,7 +117,7 @@ drawvec clean_polygon(drawvec const &geom, int z, int detail) {
size_t j;
for (j = i + 1; j < geom.size(); j++) {
if (geom[i].op != VT_LINETO) {
if (geom[j].op != VT_LINETO) {
break;
}
}