Fix cg::delaunay for some weird circular cases

This commit is contained in:
Nikita Lisitsa 2022-12-23 13:26:41 +03:00
parent eb33aa3b91
commit ee9847a904

View file

@ -4,6 +4,7 @@
#include <psemek/cg/triangulation/triangulation.hpp>
#include <queue>
#include <vector>
namespace psemek::cg
{
@ -12,6 +13,7 @@ namespace psemek::cg
auto delaunay(RobustTag robust_tag, InputIterator begin, InputIterator end)
{
std::vector<Index> edge_queue;
std::vector<Index> flipped_set;
auto at = [&](Index i){ return *(begin + i); };
@ -62,6 +64,8 @@ namespace psemek::cg
// decide if a flip is needed
if (in_circle(robust_tag, at(p0.index()), at(p1.index()), at(p2.index()), at(p3.index())) != geom::sign_t::positive) continue;
flipped_set.insert(std::lower_bound(flipped_set.begin(), flipped_set.end(), e.index()), e.index());
auto f0 = e.face();
auto f1 = twin.face();
@ -81,15 +85,17 @@ namespace psemek::cg
tprev.face(f0);
tprev.next(next); next.prev(tprev);
p0.edge(prev);
p1.edge(tnext);
p2.edge(next);
p3.edge(tprev);
f0.edge(e);
f1.edge(twin);
auto push = [&](auto e)
{
if (e.twin().face() != outer_face)
if (e.twin().face() != outer_face && !std::binary_search(flipped_set.begin(), flipped_set.end(), e.index()))
edge_queue.push_back(e.index());
};
@ -98,6 +104,8 @@ namespace psemek::cg
push(tnext);
push(tprev);
}
flipped_set.clear();
};
return detail::triangulate<Index>(robust_tag, begin, end, callback);
}