Handling of points in Convex decomposition

This commit is contained in:
Matthias Koefferlein 2025-04-16 01:15:18 +02:00
parent 60d1fb0685
commit 4f1b03496b
4 changed files with 98 additions and 8 deletions

View File

@ -542,6 +542,19 @@ Polygon::bbox () const
return box;
}
db::DPolygon
Polygon::polygon () const
{
std::vector<db::DPoint> pts;
for (int i = 0; i < int (size ()); ++i) {
pts.push_back (*vertex (i));
}
db::DPolygon poly;
poly.assign_hull (pts.begin (), pts.end ());
return poly;
}
std::pair<db::DPoint, double>
Polygon::circumcircle (bool *ok) const
{

View File

@ -562,7 +562,25 @@ public:
*/
size_t size () const
{
return mp_v.size ();
return mp_e.size ();
}
/**
* @brief Gets the internal vertexes
*
* Internal vertexes are special points inside the polygons.
*/
size_t internal_vertexes () const
{
return mp_v.size () - mp_e.size ();
}
/**
* @brief Adds a vertex as an internal vertex
*/
void add_internal_vertex (Vertex *v)
{
mp_v.push_back (v);
}
/**
@ -580,6 +598,14 @@ public:
}
}
/**
* @brief Gets the nth internal vertex
*/
inline Vertex *internal_vertex (size_t n) const
{
return mp_v[mp_e.size () + n];
}
/**
* @brief Gets the nth edge (n wraps around and can be negative)
*/
@ -604,6 +630,11 @@ public:
*/
db::DBox bbox () const;
/**
* @brief Returns a DPolygon object for this polygon
*/
db::DPolygon polygon () const;
/**
* @brief Gets the center point and radius of the circumcircle
* If ok is non-null, it will receive a boolean value indicating whether the circumcircle is valid.

View File

@ -383,12 +383,16 @@ ConvexDecomposition::hertel_mehlhorn_decomposition (Triangulation &tris, const C
left_triangles.insert (it.operator-> ());
}
std::list<std::vector<Edge *> > polygons;
std::list<std::unordered_set<Edge *> > polygons;
std::list<std::unordered_set<Vertex *> > internal_vertexes;
while (! left_triangles.empty ()) {
polygons.push_back (std::vector<Edge *> ());
std::vector<Edge *> &edges = polygons.back ();
polygons.push_back (std::unordered_set<Edge *> ());
std::unordered_set<Edge *> &edges = polygons.back ();
internal_vertexes.push_back (std::unordered_set<Vertex *> ());
std::unordered_set<Vertex *> &ivs = internal_vertexes.back ();
const Polygon *tri = *left_triangles.begin ();
std::vector<const Polygon *> queue, next_queue;
@ -407,8 +411,15 @@ ConvexDecomposition::hertel_mehlhorn_decomposition (Triangulation &tris, const C
const Edge *e = (*q)->edge (i);
const Polygon *qq = e->other (*q);
if (e->v1 ()->is_precious ()) {
ivs.insert (e->v1 ());
}
if (e->v2 ()->is_precious ()) {
ivs.insert (e->v2 ());
}
if (! qq || essential_edges.find (e) != essential_edges.end ()) {
edges.push_back (const_cast<Edge *> (e)); // @@@ const_cast
edges.insert (const_cast<Edge *> (e)); // @@@ const_cast
} else if (left_triangles.find (qq) != left_triangles.end ()) {
next_queue.push_back (qq);
}
@ -430,8 +441,12 @@ ConvexDecomposition::hertel_mehlhorn_decomposition (Triangulation &tris, const C
// create the polygons
auto iv = internal_vertexes.begin ();
for (auto p = polygons.begin (); p != polygons.end (); ++p) {
mp_graph->create_polygon (p->begin (), p->end ());
Polygon *poly = mp_graph->create_polygon (p->begin (), p->end ());
for (auto i = iv->begin (); i != iv->end (); ++i) {
poly->add_internal_vertex (*i); // @@@ reserve?
}
}
}
@ -472,7 +487,6 @@ ConvexDecomposition::decompose (const db::Polygon &poly, const std::vector<db::P
Triangulation tri (mp_graph);
tri.triangulate (poly, vertexes, param, trans);
// @@@ consider vertexes
hertel_mehlhorn_decomposition (tri, parameters);
}
@ -501,7 +515,6 @@ ConvexDecomposition::decompose (const db::DPolygon &poly, const std::vector<db::
Triangulation tri (mp_graph);
tri.triangulate (poly, vertexes, param, trans);
// @@@ consider vertexes
hertel_mehlhorn_decomposition (tri, parameters);
}

View File

@ -110,3 +110,36 @@ TEST(basic)
db::compare_layouts (_this, *ly, tl::testdata () + "/algo/hm_decomposition_au4.gds");
}
TEST(internal_vertex)
{
db::plc::Graph plc;
TestableConvexDecomposition decomp (&plc);
db::Point contour[] = {
db::Point (0, 0),
db::Point (0, 100),
db::Point (1000, 100),
db::Point (1000, 0)
};
std::vector<db::Point> vertexes;
vertexes.push_back (db::Point (10, 50));
vertexes.push_back (db::Point (200, 70));
db::Polygon poly;
poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0]));
double dbu = 0.001;
db::plc::ConvexDecompositionParameters param;
decomp.decompose (poly, vertexes, param, dbu);
for (auto p = plc.begin (); p != plc.end (); ++p) {
std::cout << p->polygon ().to_string () << std::endl; // @@@
for (size_t i = 0; i < p->internal_vertexes (); ++i) {
std::cout << " " << p->internal_vertex (i)->to_string () << std::endl; // @@@
}
}
}