mirror of https://github.com/KLayout/klayout.git
First solution, needs more testing
This commit is contained in:
parent
af6762b52d
commit
aed28098f2
|
|
@ -93,15 +93,21 @@ static bool include_zero_flag (zero_distance_mode zd_mode, const db::Edge &a, co
|
|||
*/
|
||||
bool euclidian_near_part_of_edge (zero_distance_mode zd_mode, db::coord_traits<db::Coord>::distance_type d, const db::Edge &e, const db::Edge &other, db::Edge *output)
|
||||
{
|
||||
// Handle the case of point-like basic edge: cannot determine
|
||||
// orientation
|
||||
if (e.is_degenerate ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
db::Edge g (other);
|
||||
int s1 = e.side_of (g.p1 ());
|
||||
int s2 = e.side_of (g.p2 ());
|
||||
|
||||
// s1 = side of g.p1 wrt e
|
||||
// s2 = side of g.p2 wrt e
|
||||
int s1, s2;
|
||||
if (e.is_degenerate ()) {
|
||||
if (g.contains (e.p1 ())) {
|
||||
s1 = s2 = 0;
|
||||
} else {
|
||||
s1 = s2 = -1;
|
||||
}
|
||||
} else {
|
||||
s1 = e.side_of (g.p1 ());
|
||||
s2 = e.side_of (g.p2 ());
|
||||
}
|
||||
|
||||
bool include_zero = include_zero_flag (zd_mode, e, g);
|
||||
int thr = include_zero ? 0 : -1;
|
||||
|
|
@ -115,33 +121,49 @@ bool euclidian_near_part_of_edge (zero_distance_mode zd_mode, db::coord_traits<d
|
|||
g = db::Edge (g.cut_point (e).second, g.p2 ());
|
||||
}
|
||||
|
||||
// Handle the case of point vs. edge
|
||||
// Handle the case of point vs. edge/point
|
||||
|
||||
if (g.is_degenerate ()) {
|
||||
|
||||
db::Point o = g.p1 ();
|
||||
if (e.is_degenerate ()) {
|
||||
|
||||
if (e.side_of (o) > thr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double a = e.double_sq_length ();
|
||||
double b = db::sprod (db::Vector (e.p1 () - o), e.d ()) / a;
|
||||
double c = (e.p1 ().sq_double_distance (o) - double (d) * double (d)) / a;
|
||||
|
||||
double s = b * b - c;
|
||||
if (s >= -db::epsilon) {
|
||||
double l1 = std::max (0.0, (-b - sqrt (s)));
|
||||
double l2 = std::min (1.0, (-b + sqrt (s)));
|
||||
if (l1 <= l2) {
|
||||
// point vs. point
|
||||
if (e.p1 ().distance (g.p1 ()) < double (d)) {
|
||||
if (output) {
|
||||
*output = g;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
|
||||
} else {
|
||||
|
||||
db::Point o = g.p1 ();
|
||||
|
||||
if (e.side_of (o) > thr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double a = e.double_sq_length ();
|
||||
double b = db::sprod (db::Vector (e.p1 () - o), e.d ()) / a;
|
||||
double c = (e.p1 ().sq_double_distance (o) - double (d) * double (d)) / a;
|
||||
|
||||
double s = b * b - c;
|
||||
if (s >= -db::epsilon) {
|
||||
double l1 = std::max (0.0, (-b - sqrt (s)));
|
||||
double l2 = std::min (1.0, (-b + sqrt (s)));
|
||||
if (l1 <= l2) {
|
||||
if (output) {
|
||||
*output = g;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -150,10 +172,13 @@ bool euclidian_near_part_of_edge (zero_distance_mode zd_mode, db::coord_traits<d
|
|||
double l1 = std::numeric_limits<double>::max (), l2 = -std::numeric_limits<double>::max ();
|
||||
|
||||
// handle the parallel case
|
||||
// NOTE: a point is "parallel" to an edge.
|
||||
if (e.parallel (g)) {
|
||||
|
||||
if (std::abs (double (e.distance (g.p1 ()))) >= double (d)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
double ef = 1.0 / e.double_length ();
|
||||
|
|
@ -233,16 +258,21 @@ bool euclidian_near_part_of_edge (zero_distance_mode zd_mode, db::coord_traits<d
|
|||
*/
|
||||
static bool var_near_part_of_edge (zero_distance_mode zd_mode, db::coord_traits<db::Coord>::distance_type d, db::coord_traits<db::Coord>::distance_type dd, const db::Edge &e, const db::Edge &other, db::Edge *output)
|
||||
{
|
||||
// Handle the case of point-like basic edge: cannot determine
|
||||
// orientation
|
||||
|
||||
if (e.is_degenerate ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
db::Edge g (other);
|
||||
int s1 = e.side_of (g.p1 ());
|
||||
int s2 = e.side_of (g.p2 ());
|
||||
|
||||
// s1 = side of g.p1 wrt e
|
||||
// s2 = side of g.p2 wrt e
|
||||
int s1, s2;
|
||||
if (e.is_degenerate ()) {
|
||||
if (g.contains (e.p1 ())) {
|
||||
s1 = s2 = 0;
|
||||
} else {
|
||||
s1 = s2 = -1;
|
||||
}
|
||||
} else {
|
||||
s1 = e.side_of (g.p1 ());
|
||||
s2 = e.side_of (g.p2 ());
|
||||
}
|
||||
|
||||
bool include_zero = include_zero_flag (zd_mode, e, g);
|
||||
int thr = include_zero ? 0 : -1;
|
||||
|
|
@ -259,37 +289,53 @@ static bool var_near_part_of_edge (zero_distance_mode zd_mode, db::coord_traits<
|
|||
// Handle the case of point vs. edge
|
||||
|
||||
if (g.is_degenerate ()) {
|
||||
if (e.side_of (g.p1 ()) > thr) {
|
||||
return false;
|
||||
}
|
||||
if (double (e.distance (g.p1 ())) <= -double (d)) {
|
||||
return false;
|
||||
}
|
||||
if (db::sprod (db::Vector (g.p1 () - e.p1 ()), e.d ()) < -(dd * e.double_length ())) {
|
||||
return false;
|
||||
}
|
||||
if (db::sprod (db::Vector (e.p2 () - g.p1 ()), e.d ()) < -(dd * e.double_length ())) {
|
||||
return false;
|
||||
|
||||
if (! e.is_degenerate ()) {
|
||||
if (e.side_of (g.p1 ()) > thr) {
|
||||
return false;
|
||||
}
|
||||
if (db::sprod (db::Vector (g.p1 () - e.p1 ()), e.d ()) < -(dd * e.double_length ())) {
|
||||
return false;
|
||||
}
|
||||
if (db::sprod (db::Vector (e.p2 () - g.p1 ()), e.d ()) < -(dd * e.double_length ())) {
|
||||
return false;
|
||||
}
|
||||
if (double (e.distance (g.p1 ())) <= -double (d)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// point to point
|
||||
if (e.p1 ().distance (g.p1 ()) >= double (d)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (output) {
|
||||
*output = g;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// Determine body interactions (projected mode)
|
||||
|
||||
double l1 = std::numeric_limits<double>::min (), l2 = std::numeric_limits<double>::max ();
|
||||
double l1 = std::numeric_limits<double>::lowest (), l2 = std::numeric_limits<double>::max ();
|
||||
|
||||
double ef = 1.0 / e.double_length ();
|
||||
db::DVector ep = db::DVector (ef * e.dx (), ef * e.dy ());
|
||||
db::DVector en = db::DVector (ef * e.dy (), -ef * e.dx ());
|
||||
db::DVector ep, en;
|
||||
double ef = 0.0;
|
||||
if (! e.is_degenerate ()) {
|
||||
ef = 1.0 / e.double_length ();
|
||||
ep = db::DVector (ef * e.dx (), ef * e.dy ());
|
||||
en = db::DVector (ef * e.dy (), -ef * e.dx ());
|
||||
}
|
||||
|
||||
// handle the parallel case
|
||||
if (e.parallel (g)) {
|
||||
|
||||
if (std::abs (double (e.distance (g.p1 ()))) >= double (d)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
db::DPoint e1d = db::DPoint (e.p1 ()) + en * double (d);
|
||||
|
|
@ -307,10 +353,21 @@ static bool var_near_part_of_edge (zero_distance_mode zd_mode, db::coord_traits<
|
|||
}
|
||||
|
||||
if (db::sprod_sign (e, g) == 0) {
|
||||
if (db::sprod (db::Vector (g.p1 () - e.p1 ()), e.d ()) < -(dd * e.double_length ()) ||
|
||||
db::sprod (db::Vector (e.p2 () - g.p1 ()), e.d ()) < -(dd * e.double_length ())) {
|
||||
return false;
|
||||
|
||||
if (! g.is_degenerate ()) {
|
||||
|
||||
if (db::sprod (db::Vector (g.p1 () - e.p1 ()), e.d ()) < -(dd * e.double_length ()) ||
|
||||
db::sprod (db::Vector (e.p2 () - g.p1 ()), e.d ()) < -(dd * e.double_length ())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double l = db::sprod (db::DVector (e.p1 () - g.p1 ()), db::DVector (g.d ())) / g.double_sq_length ();
|
||||
double dl = double (dd) / g.double_length ();
|
||||
l1 = l - dl;
|
||||
l2 = l + dl;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
double det = db::vprod (db::DVector (g.d ()), en);
|
||||
|
|
@ -410,7 +467,9 @@ EdgeRelationFilter::check (const db::Edge &a, const db::Edge &b, db::EdgePair *o
|
|||
|
||||
// Check whether the edges have an angle less than the ignore_angle parameter
|
||||
|
||||
if (m_ignore_angle == 90.0) {
|
||||
if (a.is_degenerate () || b.is_degenerate ()) {
|
||||
// accept dots as "always good"
|
||||
} else if (m_ignore_angle == 90.0) {
|
||||
if (db::sprod_sign (aa, b) >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2055,3 +2055,14 @@ TEST(145d_edges_merge)
|
|||
run_test (_this, "145", true);
|
||||
}
|
||||
|
||||
// issue 2141
|
||||
TEST(146_edges_and_corners)
|
||||
{
|
||||
run_test (_this, "146", false);
|
||||
}
|
||||
|
||||
TEST(146d_edges_and_corners)
|
||||
{
|
||||
run_test (_this, "146", true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
source $drc_test_source
|
||||
target $drc_test_target
|
||||
|
||||
if $drc_test_deep
|
||||
deep
|
||||
end
|
||||
|
||||
l1 = input(1, 0)
|
||||
l2 = input(2, 0)
|
||||
|
||||
l1.output(1, 0)
|
||||
l2.output(2, 0)
|
||||
l1e = l1.edges
|
||||
l2e = l2.edges
|
||||
l1c = l1.corners(as_dots)
|
||||
l2c = l2.corners(as_dots)
|
||||
|
||||
l1e.sep(l2c, 0.6).output(100, 0)
|
||||
l1c.sep(l2e, 0.6).output(101, 0)
|
||||
l1c.sep(l2c, 0.6).output(102, 0)
|
||||
l1e.enc(l2c, 0.6).output(103, 0)
|
||||
l1c.enc(l2e, 0.6).output(104, 0)
|
||||
l1c.enc(l2c, 0.6).output(105, 0)
|
||||
l2e.width(1.0).output(106, 0)
|
||||
l2c.width(1.0).output(107, 0)
|
||||
l2e.space(2.0).output(108, 0)
|
||||
l2c.space(2.0).output(109, 0)
|
||||
|
||||
l1e.sep(l2c, 0.6, square).output(110, 0)
|
||||
l1c.sep(l2e, 0.6, square).output(111, 0)
|
||||
l1c.sep(l2c, 0.6, square).output(112, 0)
|
||||
l1e.enc(l2c, 0.6, square).output(113, 0)
|
||||
l1c.enc(l2e, 0.6, square).output(114, 0)
|
||||
l1c.enc(l2c, 0.6, square).output(115, 0)
|
||||
l2e.width(1.0, square).output(116, 0)
|
||||
l2c.width(1.0, square).output(117, 0)
|
||||
l2e.space(2.0, square).output(118, 0)
|
||||
l2c.space(2.0, square).output(119, 0)
|
||||
|
||||
l1e.sep(l2c, 0.6, projection).output(120, 0)
|
||||
l1c.sep(l2e, 0.6, projection).output(121, 0)
|
||||
l1c.sep(l2c, 0.6, projection).output(122, 0)
|
||||
l1e.enc(l2c, 0.6, projection).output(123, 0)
|
||||
l1c.enc(l2e, 0.6, projection).output(124, 0)
|
||||
l1c.enc(l2c, 0.6, projection).output(125, 0)
|
||||
l2e.width(1.0, projection).output(126, 0)
|
||||
l2c.width(1.0, projection).output(127, 0)
|
||||
l2e.space(2.0, projection).output(128, 0)
|
||||
l2c.space(2.0, projection).output(129, 0)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue