Find a common-edge transition if it's the first point of the ring

This commit is contained in:
Eric Fischer
2016-10-05 17:16:18 -07:00
parent 2bc9e15975
commit 6b4076684c
+41 -26
View File
@@ -611,27 +611,41 @@ void find_common_edges(std::vector<partial> &partials) {
for (size_t i = 0; i < partials.size(); i++) { for (size_t i = 0; i < partials.size(); i++) {
if (partials[i].t == VT_POLYGON) { if (partials[i].t == VT_POLYGON) {
for (size_t j = 0; j < partials[i].geoms.size(); j++) { for (size_t j = 0; j < partials[i].geoms.size(); j++) {
for (size_t k = 0; k < partials[i].geoms[j].size(); k++) { drawvec &g = partials[i].geoms[j];
partials[i].geoms[j][k].necessary = 0;
for (size_t k = 0; k < g.size(); k++) {
g[k].necessary = 0;
} }
for (size_t k = 1; k + 1 < partials[i].geoms[j].size(); k++) { for (size_t a = 0; a < g.size(); a++) {
if (partials[i].geoms[j][k].op == VT_LINETO && partials[i].geoms[j][k + 1].op == VT_LINETO) { if (g[a].op == VT_MOVETO) {
size_t b;
for (b = a + 1; b < g.size(); b++) {
if (g[b].op != VT_LINETO) {
break;
}
}
// -1 because of duplication at the end
size_t s = b - a - 1;
for (size_t k = 0; k < s; k++) {
drawvec left, right; drawvec left, right;
if (partials[i].geoms[j][k - 1] < partials[i].geoms[j][k]) { if (g[a + (k - 1 + s) % s] < g[a + k]) {
left.push_back(partials[i].geoms[j][k - 1]); left.push_back(g[a + (k - 1 + s) % s]);
left.push_back(partials[i].geoms[j][k]); left.push_back(g[a + k]);
} else { } else {
left.push_back(partials[i].geoms[j][k]); left.push_back(g[a + k]);
left.push_back(partials[i].geoms[j][k - 1]); left.push_back(g[a + (k - 1 + s) % s]);
} }
if (partials[i].geoms[j][k] < partials[i].geoms[j][k + 1]) { if (g[a + k] < g[a + k + 1]) {
right.push_back(partials[i].geoms[j][k]); right.push_back(g[a + k]);
right.push_back(partials[i].geoms[j][k + 1]); right.push_back(g[a + k + 1]);
} else { } else {
right.push_back(partials[i].geoms[j][k + 1]); right.push_back(g[a + k + 1]);
right.push_back(partials[i].geoms[j][k]); right.push_back(g[a + k]);
} }
auto e1 = edges.find(left); auto e1 = edges.find(left);
@@ -660,42 +674,43 @@ void find_common_edges(std::vector<partial> &partials) {
} }
if (e1->second != e2->second) { if (e1->second != e2->second) {
partials[i].geoms[j][k].necessary = 1; g[a + k].necessary = 1;
// printf("%lld,%lld\n", partials[i].geoms[j][k].x, partials[i].geoms[j][k].y);
} }
} }
a = b - 1;
}
} }
// Roll rings that include a necessary point around so they start at one // Roll rings that include a necessary point around so they start at one
for (size_t k = 0; k < partials[i].geoms[j].size(); k++) { for (size_t k = 0; k < g.size(); k++) {
if (partials[i].geoms[j][k].op == VT_MOVETO) { if (g[k].op == VT_MOVETO) {
ssize_t necessary = -1; ssize_t necessary = -1;
size_t l; size_t l;
for (l = k + 1; l < partials[i].geoms[j].size(); l++) { for (l = k + 1; l < g.size(); l++) {
if (partials[i].geoms[j][l].op != VT_LINETO) { if (g[l].op != VT_LINETO) {
break; break;
} }
if (partials[i].geoms[j][l].necessary) { if (g[l].necessary) {
necessary = l; necessary = l;
} }
} }
if (necessary >= 0) { if (necessary >= 0) {
printf("roll %lu to %lu with %lu\n", k, l, necessary);
drawvec tmp; drawvec tmp;
// l - 1 because the endpoint is duplicated // l - 1 because the endpoint is duplicated
for (size_t m = necessary; m < l - 1; m++) { for (size_t m = necessary; m < l - 1; m++) {
tmp.push_back(partials[i].geoms[j][m]); tmp.push_back(g[m]);
} }
for (size_t m = k; m < necessary; m++) { for (size_t m = k; m < necessary; m++) {
tmp.push_back(partials[i].geoms[j][m]); tmp.push_back(g[m]);
} }
// replace the endpoint // replace the endpoint
tmp.push_back(partials[i].geoms[j][necessary]); tmp.push_back(g[necessary]);
if (tmp.size() != l - k) { if (tmp.size() != l - k) {
fprintf(stderr, "internal error shifting ring\n"); fprintf(stderr, "internal error shifting ring\n");
@@ -709,7 +724,7 @@ void find_common_edges(std::vector<partial> &partials) {
tmp[m].op = VT_LINETO; tmp[m].op = VT_LINETO;
} }
partials[i].geoms[j][k + m] = tmp[m]; g[k + m] = tmp[m];
} }
} }