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)
|
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);
|
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);
|
bool include_zero = include_zero_flag (zd_mode, e, g);
|
||||||
int thr = include_zero ? 0 : -1;
|
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 ());
|
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 ()) {
|
if (g.is_degenerate ()) {
|
||||||
|
|
||||||
db::Point o = g.p1 ();
|
if (e.is_degenerate ()) {
|
||||||
|
|
||||||
if (e.side_of (o) > thr) {
|
// point vs. point
|
||||||
return false;
|
if (e.p1 ().distance (g.p1 ()) < double (d)) {
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
if (output) {
|
||||||
*output = g;
|
*output = g;
|
||||||
}
|
}
|
||||||
return true;
|
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 ();
|
double l1 = std::numeric_limits<double>::max (), l2 = -std::numeric_limits<double>::max ();
|
||||||
|
|
||||||
// handle the parallel case
|
// handle the parallel case
|
||||||
|
// NOTE: a point is "parallel" to an edge.
|
||||||
if (e.parallel (g)) {
|
if (e.parallel (g)) {
|
||||||
|
|
||||||
if (std::abs (double (e.distance (g.p1 ()))) >= double (d)) {
|
if (std::abs (double (e.distance (g.p1 ()))) >= double (d)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
double ef = 1.0 / e.double_length ();
|
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)
|
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);
|
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);
|
bool include_zero = include_zero_flag (zd_mode, e, g);
|
||||||
int thr = include_zero ? 0 : -1;
|
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
|
// Handle the case of point vs. edge
|
||||||
|
|
||||||
if (g.is_degenerate ()) {
|
if (g.is_degenerate ()) {
|
||||||
if (e.side_of (g.p1 ()) > thr) {
|
|
||||||
return false;
|
if (! e.is_degenerate ()) {
|
||||||
}
|
if (e.side_of (g.p1 ()) > thr) {
|
||||||
if (double (e.distance (g.p1 ())) <= -double (d)) {
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
if (db::sprod (db::Vector (g.p1 () - e.p1 ()), e.d ()) < -(dd * e.double_length ())) {
|
||||||
if (db::sprod (db::Vector (g.p1 () - e.p1 ()), e.d ()) < -(dd * e.double_length ())) {
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
if (db::sprod (db::Vector (e.p2 () - g.p1 ()), e.d ()) < -(dd * e.double_length ())) {
|
||||||
if (db::sprod (db::Vector (e.p2 () - g.p1 ()), e.d ()) < -(dd * e.double_length ())) {
|
return false;
|
||||||
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) {
|
if (output) {
|
||||||
*output = g;
|
*output = g;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine body interactions (projected mode)
|
// 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, en;
|
||||||
db::DVector ep = db::DVector (ef * e.dx (), ef * e.dy ());
|
double ef = 0.0;
|
||||||
db::DVector en = db::DVector (ef * e.dy (), -ef * e.dx ());
|
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
|
// handle the parallel case
|
||||||
if (e.parallel (g)) {
|
if (e.parallel (g)) {
|
||||||
|
|
||||||
if (std::abs (double (e.distance (g.p1 ()))) >= double (d)) {
|
if (std::abs (double (e.distance (g.p1 ()))) >= double (d)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
db::DPoint e1d = db::DPoint (e.p1 ()) + en * double (d);
|
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_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 ())) {
|
if (! g.is_degenerate ()) {
|
||||||
return false;
|
|
||||||
|
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 {
|
} else {
|
||||||
|
|
||||||
double det = db::vprod (db::DVector (g.d ()), en);
|
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
|
// 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) {
|
if (db::sprod_sign (aa, b) >= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2055,3 +2055,14 @@ TEST(145d_edges_merge)
|
||||||
run_test (_this, "145", true);
|
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