This commit is contained in:
Matthias Koefferlein 2023-08-20 10:19:11 +02:00
parent 5de45000db
commit 1b60adf6c1
4 changed files with 83 additions and 25 deletions

View File

@ -219,7 +219,7 @@ const double triangulation_dbu = 0.001;
TriangulationProcessor::TriangulationProcessor (double max_area, double min_b)
{
m_param.max_area = max_area;
m_param.max_area = max_area * triangulation_dbu * triangulation_dbu;
m_param.base_verbosity = 40;
m_param.min_length = 2 * triangulation_dbu;
m_param.min_b = min_b;
@ -228,15 +228,18 @@ TriangulationProcessor::TriangulationProcessor (double max_area, double min_b)
void
TriangulationProcessor::process (const db::Polygon &poly, std::vector<db::Polygon> &result) const
{
// NOTE: we center the polygon for better numerical stability
db::CplxTrans trans = db::CplxTrans (triangulation_dbu) * db::ICplxTrans (db::Trans (db::Point () - poly.box ().center ()));
db::Triangles tri;
tri.triangulate (poly, m_param, triangulation_dbu);
tri.triangulate (poly, m_param, trans);
db::Point pts [3];
auto dbu_trans = db::CplxTrans (triangulation_dbu).inverted ();
auto trans_inv = trans.inverted ();
for (auto t = tri.begin (); t != tri.end (); ++t) {
for (int i = 0; i < 3; ++i) {
pts [i] = dbu_trans * *t->vertex (i);
pts [i] = trans_inv * *t->vertex (i);
}
result.push_back (db::Polygon ());
result.back ().assign_hull (pts + 0, pts + 3);

View File

@ -415,7 +415,7 @@ Triangles::find_closest_edge (const db::DPoint &p, db::Vertex *vstart, bool insi
size_t n = m_vertex_heap.size ();
size_t m = n;
// A sample heuristics that takes a sqrt(N) sample from the
// A simple heuristics that takes a sqrt(N) sample from the
// vertexes to find a good starting point
vstart = mp_triangles.begin ()->vertex (0);
@ -1432,13 +1432,12 @@ Triangles::make_contours (const Poly &poly, const Trans &trans, std::vector<std:
}
void
Triangles::create_constrained_delaunay (const db::Region &region, double dbu)
Triangles::create_constrained_delaunay (const db::Region &region, const CplxTrans &trans)
{
clear ();
std::vector<std::vector<db::Vertex *> > edge_contours;
db::CplxTrans trans (dbu);
for (auto p = region.begin_merged (); ! p.at_end (); ++p) {
make_contours (*p, trans, edge_contours);
}
@ -1447,12 +1446,12 @@ Triangles::create_constrained_delaunay (const db::Region &region, double dbu)
}
void
Triangles::create_constrained_delaunay (const db::Polygon &p, double dbu)
Triangles::create_constrained_delaunay (const db::Polygon &p, const CplxTrans &trans)
{
clear ();
std::vector<std::vector<db::Vertex *> > edge_contours;
make_contours (p, db::CplxTrans (dbu), edge_contours);
make_contours (p, trans, edge_contours);
constrain (edge_contours);
}
@ -1506,7 +1505,16 @@ Triangles::triangulate (const db::Region &region, const TriangulateParameters &p
{
tl::SelfTimer timer (tl::verbosity () > parameters.base_verbosity, "Triangles::triangulate");
create_constrained_delaunay (region, dbu);
create_constrained_delaunay (region, db::CplxTrans (dbu));
refine (parameters);
}
void
Triangles::triangulate (const db::Region &region, const TriangulateParameters &parameters, const db::CplxTrans &trans)
{
tl::SelfTimer timer (tl::verbosity () > parameters.base_verbosity, "Triangles::triangulate");
create_constrained_delaunay (region, trans);
refine (parameters);
}
@ -1515,7 +1523,16 @@ Triangles::triangulate (const db::Polygon &poly, const TriangulateParameters &pa
{
tl::SelfTimer timer (tl::verbosity () > parameters.base_verbosity, "Triangles::triangulate");
create_constrained_delaunay (poly, dbu);
create_constrained_delaunay (poly, db::CplxTrans (dbu));
refine (parameters);
}
void
Triangles::triangulate (const db::Polygon &poly, const TriangulateParameters &parameters, const db::CplxTrans &trans)
{
tl::SelfTimer timer (tl::verbosity () > parameters.base_verbosity, "Triangles::triangulate");
create_constrained_delaunay (poly, trans);
refine (parameters);
}
@ -1582,13 +1599,10 @@ Triangles::refine (const TriangulateParameters &parameters)
if ((*t)->contains (center) >= 0) {
// heuristics #1: never insert a point into a triangle with more than one segments
if (t->get ()->num_segments () <= 1) {
if (tl::verbosity () >= parameters.base_verbosity + 20) {
tl::info << "Inserting in-triangle center " << center.to_string () << " of " << (*t)->to_string (true);
}
insert_point (center, &new_triangles);
if (tl::verbosity () >= parameters.base_verbosity + 20) {
tl::info << "Inserting in-triangle center " << center.to_string () << " of " << (*t)->to_string (true);
}
insert_point (center, &new_triangles);
} else {

View File

@ -154,10 +154,10 @@ public:
*/
void triangulate (const db::Region &region, const TriangulateParameters &parameters, double dbu = 1.0);
/**
* @brief Triangulates a polygon
*/
// more versions
void triangulate (const db::Polygon &poly, const TriangulateParameters &parameters, double dbu = 1.0);
void triangulate (const db::Region &region, const TriangulateParameters &parameters, const db::CplxTrans &trans = db::CplxTrans ());
void triangulate (const db::Polygon &poly, const TriangulateParameters &parameters, const db::CplxTrans &trans = db::CplxTrans ());
/**
* @brief Triangulates a floating-point polygon
@ -279,12 +279,12 @@ protected:
/**
* @brief Creates a constrained Delaunay triangulation from the given Region
*/
void create_constrained_delaunay (const db::Region &region, double dbu = 1.0);
void create_constrained_delaunay (const db::Region &region, const db::CplxTrans &trans = db::CplxTrans ());
/**
* @brief Creates a constrained Delaunay triangulation from the given Polygon
*/
void create_constrained_delaunay (const db::Polygon &poly, double dbu = 1.0);
void create_constrained_delaunay (const db::Polygon &poly, const db::CplxTrans &trans = db::CplxTrans ());
/**
* @brief Creates a constrained Delaunay triangulation from the given DPolygon

View File

@ -665,7 +665,7 @@ TEST(create_constrained_delaunay)
"((0, 1000), (200, 800), (200, 200))");
}
TEST(triangulate)
TEST(triangulate_basic)
{
db::Region r;
r.insert (db::Box (0, 0, 10000, 10000));
@ -765,7 +765,7 @@ void read_polygons (const std::string &path, db::Region &region, double dbu)
}
}
TEST(triangulate2)
TEST(triangulate_geo)
{
double dbu = 0.001;
@ -816,7 +816,7 @@ TEST(triangulate2)
EXPECT_LT (tri.num_triangles (), size_t (30000));
}
TEST(triangulate3)
TEST(triangulate_analytic)
{
double dbu = 0.0001;
@ -869,3 +869,44 @@ TEST(triangulate3)
EXPECT_GT (tri.num_triangles (), size_t (1250));
EXPECT_LT (tri.num_triangles (), size_t (1300));
}
TEST(triangulate_problematic)
{
db::DPoint contour[] = {
db::DPoint (129145.00000, -30060.80000),
db::DPoint (129145.00000, -28769.50000),
db::DPoint (129159.50000, -28754.90000),
db::DPoint (129159.60000, -28754.80000),
db::DPoint (129159.50000, -28754.70000),
db::DPoint (129366.32200, -28547.90000),
db::DPoint (130958.54600, -26955.84600),
db::DPoint (131046.25000, -27043.55000),
db::DPoint (130152.15000, -27937.65000),
db::DPoint (130152.15000, -30060.80000)
};
db::DPolygon poly;
poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0]));
db::Triangles::TriangulateParameters param;
param.min_b = 1.0;
param.max_area = 10000.0;
param.min_length = 0.002;
TestableTriangles tri;
tri.triangulate (poly, param);
EXPECT_EQ (tri.check (false), true);
// for debugging:
// tri.dump ("debug.gds");
for (auto t = tri.begin (); t != tri.end (); ++t) {
EXPECT_LE (t->area (), param.max_area);
EXPECT_GE (t->b (), param.min_b);
}
EXPECT_GT (tri.num_triangles (), size_t (1250));
EXPECT_LT (tri.num_triangles (), size_t (1300));
}