Skip to content

Commit e849d42

Browse files
committed
Bow spindle polygons out in the center to prevent collapse
1 parent c592027 commit e849d42

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

polygon.cpp

+29-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ struct point {
3434

3535
typedef std::pair<point, point> segment;
3636

37-
void fix_opposites(std::vector<segment> &segs) {
37+
bool fix_opposites(std::vector<segment> &segs) {
38+
bool changed = false;
3839
std::multimap<segment, size_t> opposites;
3940
segment erased = std::make_pair(point(INT_MAX, INT_MAX), point(INT_MAX, INT_MAX));
4041

@@ -54,8 +55,28 @@ void fix_opposites(std::vector<segment> &segs) {
5455
continue;
5556
}
5657

57-
segs[i] = erased;
58-
segs[f.first->second] = erased;
58+
double dx = std::round(segs[i].second.x) - std::round(segs[i].first.x);
59+
double dy = std::round(segs[i].second.y) - std::round(segs[i].first.y);
60+
double dsq = dx * dx + dy * dy;
61+
if (dsq >= 5 * 5) {
62+
// alter the segments instead to keep it from collapsing away
63+
64+
double ang = atan2(dy, dx) + M_PI / 2;
65+
double cx = std::round((std::round(segs[i].second.x) + std::round(segs[i].first.x)) / 2 + sqrt(2) / 2 * cos(ang));
66+
double cy = std::round((std::round(segs[i].second.y) + std::round(segs[i].first.y)) / 2 + sqrt(2) / 2 * sin(ang));
67+
68+
segs.emplace_back(point(cx, cy), segs[i].second);
69+
segs[i] = std::make_pair(segs[i].first, point(cx, cy));
70+
changed = true;
71+
72+
// segs[i] is not erased, so segs[f.first->second]
73+
// will still match against it and will be bowed out
74+
// in the opposite direction.
75+
} else {
76+
segs[i] = erased;
77+
segs[f.first->second] = erased;
78+
}
79+
5980
opposites.erase(f.first);
6081
break;
6182
}
@@ -68,6 +89,7 @@ void fix_opposites(std::vector<segment> &segs) {
6889
}
6990
}
7091
segs.resize(out);
92+
return changed;
7193
}
7294

7395
const std::pair<double, double> SAME_SLOPE = std::make_pair(-INT_MAX, INT_MAX);
@@ -297,7 +319,10 @@ void snap_round(std::vector<segment> &segs) {
297319
// in the course of trying to keep spindles alive, and will then need to
298320
// resolve those.
299321

300-
fix_opposites(segs);
322+
if (fix_opposites(segs)) {
323+
again = true;
324+
continue;
325+
}
301326

302327
// set up for a scanline traversal of the segments
303328
// to find the pairs that intersect

0 commit comments

Comments
 (0)