Implementing additional vertexes for triangulation

This commit is contained in:
Matthias Koefferlein 2025-03-23 11:34:13 +01:00
parent 8727c31d36
commit 71644fa56c
5 changed files with 87 additions and 14 deletions

View File

@ -32,19 +32,19 @@ namespace db
// Vertex implementation
Vertex::Vertex ()
: DPoint (), m_level (0)
: DPoint (), m_is_precious (false)
{
// .. nothing yet ..
}
Vertex::Vertex (const db::DPoint &p)
: DPoint (p), m_level (0)
: DPoint (p), m_is_precious (false)
{
// .. nothing yet ..
}
Vertex::Vertex (const Vertex &v)
: DPoint (), m_level (0)
: DPoint (), m_is_precious (false)
{
operator= (v);
}
@ -54,13 +54,13 @@ Vertex &Vertex::operator= (const Vertex &v)
if (this != &v) {
// NOTE: edges are not copied!
db::DPoint::operator= (v);
m_level = v.m_level;
m_is_precious = v.m_is_precious;
}
return *this;
}
Vertex::Vertex (db::DCoord x, db::DCoord y)
: DPoint (x, y), m_level (0)
: DPoint (x, y), m_is_precious (false)
{
// .. nothing yet ..
}

View File

@ -74,8 +74,8 @@ public:
bool has_edge (const TriangleEdge *edge) const;
size_t level () const { return m_level; }
void set_level (size_t l) { m_level = l; }
void set_is_precious (bool f) { m_is_precious = f; }
bool is_precious () const { return m_is_precious; }
std::string to_string (bool with_id = false) const;
@ -102,7 +102,7 @@ private:
}
edges_type mp_edges;
size_t m_level;
bool m_is_precious;
};
/**

View File

@ -1484,7 +1484,7 @@ Triangles::create_constrained_delaunay (const db::Polygon &p, const std::vector<
clear ();
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
insert_point (trans * *v);
insert_point (trans * *v)->set_is_precious (true);
}
std::vector<std::vector<db::Vertex *> > edge_contours;
@ -1499,7 +1499,7 @@ Triangles::create_constrained_delaunay (const db::DPolygon &p, const std::vector
clear ();
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
insert_point (trans * *v);
insert_point (trans * *v)->set_is_precious (true);
}
std::vector<std::vector<db::Vertex *> > edge_contours;
@ -1724,7 +1724,7 @@ Triangles::refine (const TriangulateParameters &parameters)
for (auto e = (*v)->begin_edges (); e != (*v)->end_edges () && ! has_segment; ++e) {
has_segment = (*e)->is_segment ();
}
if (! has_segment) {
if (! has_segment && ! (*v)->is_precious ()) {
to_delete.push_back (*v);
}
}

View File

@ -54,9 +54,6 @@ TEST(Vertex_basic)
v = db::Vertex (db::DPoint (2, 3));
EXPECT_EQ (v.to_string (), "(2, 3)");
v.set_level (42);
EXPECT_EQ (v.level (), size_t (42));
}
static std::string edges_from_vertex (const db::Vertex &v)

View File

@ -1000,3 +1000,79 @@ TEST(triangulate_issue1996)
EXPECT_GT (tri.num_triangles (), size_t (128000));
EXPECT_LT (tri.num_triangles (), size_t (132000));
}
TEST(triangulate_with_vertexes)
{
db::Point contour[] = {
db::Point (0, 0),
db::Point (0, 100),
db::Point (1000, 100),
db::Point (1000, 0)
};
db::Polygon poly;
poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0]));
double dbu = 0.001;
db::Triangles::TriangulateParameters param;
param.min_b = 0.0;
param.max_area = 0.0;
std::vector<db::Point> vertexes;
TestableTriangles tri;
db::CplxTrans trans = db::DCplxTrans (dbu) * db::CplxTrans (db::Trans (db::Point () - poly.box ().center ()));
tri.triangulate (poly, param, trans);
EXPECT_EQ (tri.to_string (), "((-0.5, -0.05), (-0.5, 0.05), (0.5, 0.05)), ((0.5, -0.05), (-0.5, -0.05), (0.5, 0.05))");
vertexes.clear ();
// outside vertexes are ignored, but lead to a different triangulation
vertexes.push_back (db::Point (50, 150));
tri.triangulate (poly, vertexes, param, trans);
EXPECT_EQ (tri.to_string (), "((-0.5, -0.05), (-0.133333333333, 0.05), (0.5, -0.05)), ((0.5, 0.05), (0.5, -0.05), (-0.133333333333, 0.05)), ((-0.133333333333, 0.05), (-0.5, -0.05), (-0.5, 0.05))");
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
auto *vp = tri.find_vertex_for_point (trans * *v);
EXPECT_EQ (vp, 0);
}
vertexes.clear ();
vertexes.push_back (db::Point (50, 50));
tri.triangulate (poly, vertexes, param, trans);
EXPECT_EQ (tri.to_string (), "((-0.45, 0), (-0.5, -0.05), (-0.5, 0.05)), ((0.5, 0.05), (-0.45, 0), (-0.5, 0.05)), ((-0.45, 0), (0.5, -0.05), (-0.5, -0.05)), ((-0.45, 0), (0.5, 0.05), (0.5, -0.05))");
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
auto *vp = tri.find_vertex_for_point (trans * *v);
if (! vp) {
tl::warn << "Vertex not present in output: " << v->to_string ();
EXPECT_EQ (1, 0);
}
}
// aggressive triangulation
param.min_b = 1.0;
param.max_area = 20 * 20 * dbu * dbu;
tri.triangulate (poly, vertexes, param, trans);
EXPECT_GT (tri.num_triangles (), size_t (380));
EXPECT_LT (tri.num_triangles (), size_t (400));
for (auto t = tri.begin (); t != tri.end (); ++t) {
EXPECT_LE (t->area (), param.max_area);
EXPECT_GE (t->b (), param.min_b);
}
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
auto *vp = tri.find_vertex_for_point (trans * *v);
if (! vp) {
tl::warn << "Vertex not present in output: " << v->to_string ();
EXPECT_EQ (1, 0);
}
}
}