Triangles: potential performance improvement in degenerate point set (circle) case.

This commit is contained in:
Matthias Koefferlein 2023-08-19 01:13:09 +02:00
parent 5c46cdfda3
commit ae3588ab16
3 changed files with 32 additions and 20 deletions

View File

@ -102,6 +102,21 @@ Vertex::has_edge (const TriangleEdge *edge) const
return false;
}
size_t
Vertex::num_edges (int max_count) const
{
if (max_count < 0) {
// NOTE: this can be slow for a std::list, so we have max_count to limit this effort
return mp_edges.size ();
} else {
size_t n = 0;
for (auto i = mp_edges.begin (); i != mp_edges.end () && --max_count >= 0; ++i) {
++n;
}
return n;
}
}
std::string
Vertex::to_string (bool with_id) const
{
@ -112,18 +127,6 @@ Vertex::to_string (bool with_id) const
return res;
}
void
Vertex::remove_edge (db::TriangleEdge *edge)
{
for (auto e = mp_edges.begin (); e != mp_edges.end (); ++e) {
if (*e == edge) {
mp_edges.erase (e);
return;
}
}
tl_assert (false);
}
int
Vertex::in_circle (const DPoint &point, const DPoint &center, double radius)
{
@ -172,17 +175,20 @@ void
TriangleEdge::link ()
{
mp_v1->mp_edges.push_back (this);
m_ec_v1 = --mp_v1->mp_edges.end ();
mp_v2->mp_edges.push_back (this);
m_ec_v2 = --mp_v2->mp_edges.end ();
}
void
TriangleEdge::unlink ()
{
if (mp_v1) {
mp_v1->remove_edge (this);
mp_v1->remove_edge (m_ec_v1);
}
if (mp_v2) {
mp_v2->remove_edge (this);
mp_v2->remove_edge (m_ec_v2);
}
mp_v1 = mp_v2 = 0;
}

View File

@ -48,8 +48,9 @@ class DB_PUBLIC Vertex
: public db::DPoint
{
public:
typedef std::vector<TriangleEdge *> edges_type;
typedef std::list<TriangleEdge *> edges_type;
typedef edges_type::const_iterator edges_iterator;
typedef edges_type::iterator edges_iterator_non_const;
Vertex ();
Vertex (const DPoint &p);
@ -63,7 +64,7 @@ public:
edges_iterator begin_edges () const { return mp_edges.begin (); }
edges_iterator end_edges () const { return mp_edges.end (); }
size_t num_edges () const { return mp_edges.size (); }
size_t num_edges (int max_count = -1) const;
bool has_edge (const TriangleEdge *edge) const;
@ -88,7 +89,11 @@ public:
private:
friend class TriangleEdge;
void remove_edge (db::TriangleEdge *edge);
void remove_edge (const edges_iterator_non_const &ec)
{
mp_edges.erase (ec);
}
edges_type mp_edges;
size_t m_level;
@ -397,6 +402,7 @@ private:
Vertex *mp_v1, *mp_v2;
Triangle *mp_left, *mp_right;
Vertex::edges_iterator_non_const m_ec_v1, m_ec_v2;
size_t m_level;
size_t m_id;
bool m_is_segment;

View File

@ -724,7 +724,7 @@ Triangles::remove_inside_vertex (db::Vertex *vertex, std::list<tl::weak_ptr<db::
bool make_new_triangle = true;
while (vertex->num_edges () > 3) {
while (vertex->num_edges (4) > 3) {
db::TriangleEdge *to_flip = 0;
for (auto e = vertex->begin_edges (); e != vertex->end_edges () && to_flip == 0; ++e) {
@ -746,9 +746,9 @@ Triangles::remove_inside_vertex (db::Vertex *vertex, std::list<tl::weak_ptr<db::
}
if (vertex->num_edges () > 3) {
if (vertex->num_edges (4) > 3) {
tl_assert (vertex->num_edges () == 4);
tl_assert (vertex->num_edges (5) == 4);
// This case can happen if two edges attached to the vertex are collinear
// in this case choose the "join" strategy