Skip to content

Commit

Permalink
Doing the scan line through the segments
Browse files Browse the repository at this point in the history
  • Loading branch information
e-n-f committed Nov 8, 2023
1 parent 966b911 commit 6bebc1b
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 6 deletions.
59 changes: 53 additions & 6 deletions polygon.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <stdio.h>
#include "geometry.hpp"

struct point {
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
}
Expand Down
1 change: 1 addition & 0 deletions polygon.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
drawvec clean_polygon(drawvec const &geom, int z, int detail);
6 changes: 6 additions & 0 deletions tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "errors.hpp"
#include "compression.hpp"
#include "protozero/varint.hpp"
#include "polygon.hpp"

extern "C" {
#include "jsonpull/jsonpull.h"
Expand Down Expand Up @@ -612,6 +613,11 @@ void *partial_feature_worker(void *v) {
int out_detail = (*partials)[i].extra_detail;

drawvec geom = (*partials)[i].geoms[0];

if (t == VT_POLYGON) {
clean_polygon(geom, z, out_detail);
}

to_tile_scale(geom, z, out_detail);

if (t == VT_POLYGON) {
Expand Down

0 comments on commit 6bebc1b

Please sign in to comment.