Fix handling degenerate states in cg::triangulation

This commit is contained in:
Nikita Lisitsa 2022-12-23 10:02:06 +03:00
parent e1d4608e3f
commit eb33aa3b91

View file

@ -83,6 +83,13 @@ namespace psemek::cg
auto hp0 = cur_hull_edge.origin(); auto hp0 = cur_hull_edge.origin();
auto hp1 = next_hull_edge.origin(); auto hp1 = next_hull_edge.origin();
auto reset_hull_edge = [&]{
cur_hull_edge = hull_start;
next_hull_edge = cur_hull_edge.next();
hp0 = cur_hull_edge.origin();
hp1 = next_hull_edge.origin();
};
auto move_hull_edge = [&]{ auto move_hull_edge = [&]{
cur_hull_edge = next_hull_edge; cur_hull_edge = next_hull_edge;
next_hull_edge = next_hull_edge.next(); next_hull_edge = next_hull_edge.next();
@ -108,43 +115,27 @@ namespace psemek::cg
// the whole hull is just a sequence of points on a line // the whole hull is just a sequence of points on a line
// find the closest & connect via a single edge // find the closest & connect via a single edge
auto q = result.point(0); reset_hull_edge();
bool vertical = false; auto q = cur_hull_edge.origin();
// find rightmost point
for (Index i = 1; i < result.points.size(); ++i)
{ {
auto const x = at(i)[0]; int d = (at(hp0.index())[0] == at(hp1.index())[0])
auto const qx = at(q.index())[0]; ? 1 // vertical
: 0 // horizontal
;
if (x == qx) // vertical
while (true)
{ {
vertical = true; if (at(cur_hull_edge.origin().index())[d] > at(q.index())[d])
q = cur_hull_edge.origin();
move_hull_edge();
if (cur_hull_edge == hull_start)
break; break;
} }
if (x > qx)
{
q = result.point(i);
}
}
// all points lie on a vertical line - find topmost
if (vertical)
{
q = result.point(0);
for (Index i = 1; i < result.points.size(); ++i)
{
auto const y = at(i)[1];
auto const qy = at(q.index())[1];
if (y > qy)
{
q = result.point(i);
}
}
} }
auto p = result.point(*it); auto p = result.point(*it);