Enhanced Euclidian visualization

This commit is contained in:
Matthias Koefferlein 2024-03-31 10:30:04 +02:00
parent eb1ac4903e
commit 3836874b8f
2 changed files with 51 additions and 25 deletions

View File

@ -355,36 +355,52 @@ DRCHullProcessor::DRCHullProcessor (db::Coord d, db::metrics_type metrics, size_
// .. nothing yet ..
}
static void create_edge_segment_euclidian (std::vector<db::Point> &points, const db::Edge &e, db::Coord dist, size_t n_circle)
static void create_edge_segment_euclidian (std::vector<db::Point> &points, const db::Edge &e, const db::Edge &ee, db::Coord dist, size_t n_circle)
{
db::Vector d (e.d ());
db::Vector n (-d.y (), d.x ());
if (d.x () == 0 && d.y () == 0) {
db::Vector dd (ee.d ());
db::Vector nn (-dd.y (), dd.x ());
if ((d.x () == 0 && d.y () == 0) || (dd.x () == 0 && dd.y () == 0)) {
// should not happen
return;
}
double da = M_PI * 2.0 / n_circle;
double f = dist / n.double_length ();
double f2 = f / cos (0.5 * da);
points.push_back (e.p1 ());
points.push_back (e.p1 () + db::Vector (d * -f));
for (size_t i = 0; i < n_circle / 4; ++i) {
double a = (i + 0.5) * da;
points.push_back (e.p1 () + db::Vector (d * (-f2 * cos (a)) + n * (f2 * sin (a))));
}
double ff = dist / nn.double_length ();
points.push_back (e.p1 () + db::Vector (n * f));
points.push_back (e.p2 () + db::Vector (n * f));
for (size_t i = 0; i < n_circle / 4; ++i) {
double a = (i + 0.5) * da;
points.push_back (e.p2 () + db::Vector (d * (f2 * sin (a)) + n * (f2 * cos (a))));
}
if (db::vprod_sign (nn, n) < 0) {
points.push_back (e.p2 () + db::Vector (d * f));
// concave corner
points.push_back (e.p2 ());
points.push_back (e.p2 () + db::Vector (nn * ff));
} else {
double amax;
if (db::vprod_sign (nn, n) == 0) {
amax = db::sprod_sign (nn, n) < 0 ? M_PI : 0.0;
} else {
amax = atan2 (db::vprod (nn, n), db::sprod (nn, n));
}
double da = M_PI * 2.0 / n_circle;
double f2 = f / cos (0.5 * da);
int na = int (floor (amax / da + db::epsilon));
double a0 = 0.5 * (amax - da * (na - 1));
for (int i = 0; i < na; ++i) {
double a = i * da + a0;
points.push_back (e.p2 () + db::Vector (d * (f2 * sin (a)) + n * (f2 * cos (a))));
}
}
}
static void create_edge_segment_square (std::vector<db::Point> &points, const db::Edge &e, db::Coord dist)
@ -421,10 +437,10 @@ static void create_edge_segment_projection (std::vector<db::Point> &points, cons
points.push_back (e.p2 () + db::Vector (n * f));
}
static void create_edge_segment (std::vector<db::Point> &points, db::metrics_type metrics, const db::Edge &e, db::Coord d, size_t n_circle)
static void create_edge_segment (std::vector<db::Point> &points, db::metrics_type metrics, const db::Edge &e, const db::Edge &ee, db::Coord d, size_t n_circle)
{
if (metrics == db::Euclidian) {
create_edge_segment_euclidian (points, e, d, n_circle);
create_edge_segment_euclidian (points, e, ee, d, n_circle);
} else if (metrics == db::Square) {
create_edge_segment_square (points, e, d);
} else if (metrics == db::Projection) {
@ -450,20 +466,23 @@ DRCHullProcessor::process (const db::Polygon &poly, std::vector<db::Polygon> &re
for (auto p = c.begin (); p != c.end (); ++p) {
auto pp = p;
++pp;
if (pp == c.end ()) {
if (++pp == c.end ()) {
pp = c.begin ();
}
create_edge_segment (points, m_metrics, db::Edge (*p, *pp), m_d, m_n_circle);
auto ppp = pp;
if (++ppp == c.end ()) {
ppp = c.begin ();
}
create_edge_segment (points, m_metrics, db::Edge (*p, *pp), db::Edge (*pp, *ppp), m_d, m_n_circle);
}
for (auto p = points.begin (); p != points.end (); ++p) {
auto pp = p;
++pp;
if (pp == points.end ()) {
if (++ pp == points.end ()) {
pp = points.begin ();
}

View File

@ -1458,10 +1458,17 @@ class DBRegion_TestClass < TestBase
r = RBA::Region::new()
r.insert(RBA::Polygon::new([[0, 0], [1000, 1000], [1500, 0]]))
assert_equal(r.drc_hull(RBA::Region::Euclidian, 200, 8).merged.to_s, "(-83,-200;-200,-83;-200,83;-141,141;859,1141;917,1200;953,1200;985,1216;1033,1200;1083,1200;1107,1176;1142,1164;1179,1089;1716,15;1700,-33;1700,-83;1675,-108;1664,-142;1619,-164;1583,-200)")
assert_equal(r.drc_hull(RBA::Region::Euclidian, 200, 8).merged.to_s, "(-83,-200;-200,-83;-200,83;-141,141;859,1141;950,1211;1114,1184;1179,1089;1679,89;1714,-35;1627,-176;1500,-200)")
assert_equal(r.drc_hull(RBA::Region::Square, 200).merged.to_s, "(-200,-200;-200,-82;-283,0;1000,1283;1039,1243;1089,1268;1768,-89;1700,-123;1700,-200)")
assert_equal(r.drc_hull(RBA::Region::Projection, 200).merged.to_s, "(0,-200;0,0;-141,141;859,1141;1000,1000;1179,1089;1679,89;1500,0;1500,-200)")
r = RBA::Region::new()
r.merged_semantics = false
r.insert(RBA::Polygon::new([[0, 0], [1000, 1000]], true))
assert_equal(r.drc_hull(RBA::Region::Euclidian, 200, 8).merged.to_s, "(-83,-200;-200,-83;-200,83;-141,141;859,1141;917,1200;1083,1200;1200,1083;1200,917;1141,859;141,-141;83,-200)")
assert_equal(r.drc_hull(RBA::Region::Square, 200, 8).merged.to_s, "(0,-283;-141,-141;-283,0;1000,1283;1141,1141;1283,1000)")
assert_equal(r.drc_hull(RBA::Region::Projection, 200, 8).merged.to_s, "(141,-141;-141,141;859,1141;1141,859)")
end
end