mirror of https://github.com/KLayout/klayout.git
Region to edge interactions
With this fix, regions can be interaction-tested with edge collections. Only "normal" interaction is available - select_overlapping is not. This is still confined to region to region interactions.
This commit is contained in:
parent
df46aabb2e
commit
4ad20fa4ce
|
|
@ -651,7 +651,7 @@ public:
|
|||
p = reinterpret_cast<const db::Polygon *> (o1 - 1);
|
||||
}
|
||||
|
||||
if (e && p) {
|
||||
if (e && p && m_seen.find (e) == m_seen.end ()) {
|
||||
|
||||
// A polygon and an edge interact if the edge is either inside completely
|
||||
// of at least one edge of the polygon intersects with the edge
|
||||
|
|
@ -666,7 +666,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if (interacts && m_seen.insert (e).second) {
|
||||
if (interacts) {
|
||||
m_seen.insert (e);
|
||||
mp_output->insert (*e);
|
||||
}
|
||||
|
||||
|
|
@ -706,6 +707,14 @@ struct EdgeOrRegionBoxConverter
|
|||
Edges &
|
||||
Edges::select_interacting (const Region &other)
|
||||
{
|
||||
// shortcuts
|
||||
if (other.empty ()) {
|
||||
clear ();
|
||||
return *this;
|
||||
} else if (empty ()) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
db::box_scanner<char, size_t> scanner (m_report_progress, m_progress_desc);
|
||||
scanner.reserve (size () + other.size ());
|
||||
|
||||
|
|
@ -731,6 +740,11 @@ Edges::select_interacting (const Region &other)
|
|||
Edges &
|
||||
Edges::select_not_interacting (const Region &other)
|
||||
{
|
||||
// shortcuts
|
||||
if (other.empty () || empty ()) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
db::box_scanner<char, size_t> scanner (m_report_progress, m_progress_desc);
|
||||
scanner.reserve (size () + other.size ());
|
||||
|
||||
|
|
|
|||
|
|
@ -929,7 +929,201 @@ Region::select_interacting_generic (const Region &other, int mode, bool touching
|
|||
set_valid_polygons ();
|
||||
}
|
||||
|
||||
EdgePairs
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief A helper class for the region to edge interaction functionality
|
||||
*
|
||||
* Note: This special scanner uses pointers to two different objects: edges and polygons.
|
||||
* It uses odd value pointers to indicate pointers to polygons and even value pointers to indicate
|
||||
* pointers to edges.
|
||||
*
|
||||
* There is a special box converter which is able to sort that out as well.
|
||||
*/
|
||||
template <class OutputContainer>
|
||||
class region_to_edge_interaction_filter
|
||||
: public db::box_scanner_receiver<char, size_t>
|
||||
{
|
||||
public:
|
||||
region_to_edge_interaction_filter (OutputContainer &output)
|
||||
: mp_output (&output), m_inverse (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
region_to_edge_interaction_filter (OutputContainer &output, const db::Region ®ion)
|
||||
: mp_output (&output), m_inverse (true)
|
||||
{
|
||||
for (db::Region::const_iterator p = region.begin_merged (); ! p.at_end (); ++p) {
|
||||
m_seen.insert (&*p);
|
||||
}
|
||||
}
|
||||
|
||||
void add (const char *o1, size_t p1, const char *o2, size_t p2)
|
||||
{
|
||||
const db::Edge *e = 0;
|
||||
const db::Polygon *p = 0;
|
||||
|
||||
// Note: edges have property 0 and have even-valued pointers.
|
||||
// Polygons have property 1 and odd-valued pointers.
|
||||
if (p1 == 0 && p2 == 1) {
|
||||
e = reinterpret_cast<const db::Edge *> (o1);
|
||||
p = reinterpret_cast<const db::Polygon *> (o2 - 1);
|
||||
} else if (p1 == 1 && p2 == 0) {
|
||||
e = reinterpret_cast<const db::Edge *> (o2);
|
||||
p = reinterpret_cast<const db::Polygon *> (o1 - 1);
|
||||
}
|
||||
|
||||
if (e && p && (m_seen.find (p) == m_seen.end ()) != m_inverse) {
|
||||
|
||||
// A polygon and an edge interact if the edge is either inside completely
|
||||
// of at least one edge of the polygon intersects with the edge
|
||||
bool interacts = false;
|
||||
if (p->box ().contains (e->p1 ()) && db::inside_poly (p->begin_edge (), e->p1 ()) >= 0) {
|
||||
interacts = true;
|
||||
} else {
|
||||
for (db::Polygon::polygon_edge_iterator pe = p->begin_edge (); ! pe.at_end () && ! interacts; ++pe) {
|
||||
if ((*pe).intersect (*e)) {
|
||||
interacts = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (interacts) {
|
||||
if (m_inverse) {
|
||||
m_seen.erase (p);
|
||||
} else {
|
||||
m_seen.insert (p);
|
||||
mp_output->insert (*p);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void fill_output ()
|
||||
{
|
||||
for (std::set<const db::Polygon *>::const_iterator p = m_seen.begin (); p != m_seen.end (); ++p) {
|
||||
mp_output->insert (**p);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
OutputContainer *mp_output;
|
||||
std::set<const db::Polygon *> m_seen;
|
||||
bool m_inverse;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A special box converter that splits the pointers into polygon and edge pointers
|
||||
*/
|
||||
struct EdgeOrRegionBoxConverter
|
||||
{
|
||||
typedef db::Box box_type;
|
||||
|
||||
db::Box operator() (const char &c) const
|
||||
{
|
||||
// Note: edges have property 0 and have even-valued pointers.
|
||||
// Polygons have property 1 and odd-valued pointers.
|
||||
const char *cp = &c;
|
||||
if ((size_t (cp) & 1) == 1) {
|
||||
// it's a polygon
|
||||
return (reinterpret_cast<const db::Polygon *> (cp - 1))->box ();
|
||||
} else {
|
||||
// it's an edge
|
||||
const db::Edge *e = reinterpret_cast<const db::Edge *> (cp);
|
||||
return db::Box (e->p1 (), e->p2 ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Region
|
||||
Region::selected_interacting_generic (const Edges &other, bool inverse) const
|
||||
{
|
||||
if (other.empty ()) {
|
||||
if (! inverse) {
|
||||
return Region ();
|
||||
} else {
|
||||
return *this;
|
||||
}
|
||||
} else if (empty ()) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
db::box_scanner<char, size_t> scanner (m_report_progress, m_progress_desc);
|
||||
scanner.reserve (size () + other.size ());
|
||||
|
||||
ensure_valid_polygons ();
|
||||
for (const_iterator p = begin_merged (); ! p.at_end (); ++p) {
|
||||
scanner.insert ((char *) &*p + 1, 1);
|
||||
}
|
||||
|
||||
other.ensure_valid_merged_edges ();
|
||||
for (Edges::const_iterator e = other.begin (); ! e.at_end (); ++e) {
|
||||
scanner.insert ((char *) &*e, 0);
|
||||
}
|
||||
|
||||
Region output;
|
||||
EdgeOrRegionBoxConverter bc;
|
||||
|
||||
if (! inverse) {
|
||||
region_to_edge_interaction_filter<Region> filter (output);
|
||||
scanner.process (filter, 1, bc);
|
||||
} else {
|
||||
region_to_edge_interaction_filter<Region> filter (output, *this);
|
||||
scanner.process (filter, 1, bc);
|
||||
filter.fill_output ();
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void
|
||||
Region::select_interacting_generic (const Edges &other, bool inverse)
|
||||
{
|
||||
// shortcut
|
||||
if (other.empty ()) {
|
||||
if (! inverse) {
|
||||
clear ();
|
||||
}
|
||||
return;
|
||||
} else if (empty ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
db::box_scanner<char, size_t> scanner (m_report_progress, m_progress_desc);
|
||||
scanner.reserve (size () + other.size ());
|
||||
|
||||
ensure_valid_polygons ();
|
||||
for (const_iterator p = begin_merged (); ! p.at_end (); ++p) {
|
||||
scanner.insert ((char *) &*p + 1, 1);
|
||||
}
|
||||
|
||||
other.ensure_valid_merged_edges ();
|
||||
for (Edges::const_iterator e = other.begin (); ! e.at_end (); ++e) {
|
||||
scanner.insert ((char *) &*e, 0);
|
||||
}
|
||||
|
||||
db::Shapes output (false);
|
||||
EdgeOrRegionBoxConverter bc;
|
||||
|
||||
if (! inverse) {
|
||||
region_to_edge_interaction_filter<db::Shapes> filter (output);
|
||||
scanner.process (filter, 1, bc);
|
||||
} else {
|
||||
region_to_edge_interaction_filter<db::Shapes> filter (output, *this);
|
||||
scanner.process (filter, 1, bc);
|
||||
filter.fill_output ();
|
||||
}
|
||||
|
||||
m_polygons.swap (output);
|
||||
set_valid_polygons ();
|
||||
}
|
||||
|
||||
EdgePairs
|
||||
Region::grid_check (db::Coord gx, db::Coord gy) const
|
||||
{
|
||||
EdgePairs out;
|
||||
|
|
|
|||
|
|
@ -1199,9 +1199,6 @@ public:
|
|||
/**
|
||||
* @brief Selects all polygons of this region which are completly outside polygons from the other region
|
||||
*
|
||||
* This method does not merge the polygons before using them. If whole connected
|
||||
* regions shall be selected, merge the region first.
|
||||
*
|
||||
* Merged semantics applies.
|
||||
*/
|
||||
Region &select_outside (const Region &other)
|
||||
|
|
@ -1213,9 +1210,6 @@ public:
|
|||
/**
|
||||
* @brief Selects all polygons of this region which are not completly outside polygons from the other region
|
||||
*
|
||||
* This method does not merge the polygons before using them. If whole connected
|
||||
* regions shall be selected, merge the region first.
|
||||
*
|
||||
* Merged semantics applies.
|
||||
*/
|
||||
Region &select_not_outside (const Region &other)
|
||||
|
|
@ -1251,9 +1245,6 @@ public:
|
|||
/**
|
||||
* @brief Selects all polygons of this region which are completly inside polygons from the other region
|
||||
*
|
||||
* This method does not merge the polygons before using them. If whole connected
|
||||
* regions shall be selected, merge the region first.
|
||||
*
|
||||
* Merged semantics applies.
|
||||
*/
|
||||
Region &select_inside (const Region &other)
|
||||
|
|
@ -1265,9 +1256,6 @@ public:
|
|||
/**
|
||||
* @brief Selects all polygons of this region which are not completly inside polygons from the other region
|
||||
*
|
||||
* This method does not merge the polygons before using them. If whole connected
|
||||
* regions shall be selected, merge the region first.
|
||||
*
|
||||
* Merged semantics applies.
|
||||
*/
|
||||
Region &select_not_inside (const Region &other)
|
||||
|
|
@ -1303,9 +1291,6 @@ public:
|
|||
/**
|
||||
* @brief Selects all polygons of this region which overlap or touch polygons from the other region
|
||||
*
|
||||
* This method does not merge the polygons before using them. If whole connected
|
||||
* regions shall be selected, merge the region first.
|
||||
*
|
||||
* Merged semantics applies.
|
||||
*/
|
||||
Region &select_interacting (const Region &other)
|
||||
|
|
@ -1317,9 +1302,6 @@ public:
|
|||
/**
|
||||
* @brief Selects all polygons of this region which do not overlap or touch polygons from the other region
|
||||
*
|
||||
* This method does not merge the polygons before using them. If whole connected
|
||||
* regions shall be selected, merge the region first.
|
||||
*
|
||||
* Merged semantics applies.
|
||||
*/
|
||||
Region &select_not_interacting (const Region &other)
|
||||
|
|
@ -1353,10 +1335,53 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Selects all polygons of this region which overlap polygons from the other region
|
||||
* @brief Selects all polygons of this region which overlap or touch edges from the given edge collection
|
||||
*
|
||||
* This method does not merge the polygons before using them. If whole connected
|
||||
* regions shall be selected, merge the region first.
|
||||
* Merged semantics applies to both operators.
|
||||
*/
|
||||
Region &select_interacting (const Edges &other)
|
||||
{
|
||||
select_interacting_generic (other, false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Selects all polygons of this region which do not overlap or touch edges from the edge collection
|
||||
*
|
||||
* Merged semantics applies to both operators.
|
||||
*/
|
||||
Region &select_not_interacting (const Edges &other)
|
||||
{
|
||||
select_interacting_generic (other, true);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns all polygons of this which overlap or touch edges from the edge collection
|
||||
*
|
||||
* This method is an out-of-place version of select_interacting.
|
||||
*
|
||||
* Merged semantics applies to both operators.
|
||||
*/
|
||||
Region selected_interacting (const Edges &other) const
|
||||
{
|
||||
return selected_interacting_generic (other, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns all polygons of this which do not overlap or touch polygons from the other region
|
||||
*
|
||||
* This method is an out-of-place version of select_not_interacting.
|
||||
*
|
||||
* Merged semantics applies to both operators.
|
||||
*/
|
||||
Region selected_not_interacting (const Edges &other) const
|
||||
{
|
||||
return selected_interacting_generic (other, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Selects all polygons of this region which overlap polygons from the other region
|
||||
*
|
||||
* Merged semantics applies.
|
||||
*/
|
||||
|
|
@ -1369,9 +1394,6 @@ public:
|
|||
/**
|
||||
* @brief Selects all polygons of this region which do not overlap polygons from the other region
|
||||
*
|
||||
* This method does not merge the polygons before using them. If whole connected
|
||||
* regions shall be selected, merge the region first.
|
||||
*
|
||||
* Merged semantics applies.
|
||||
*/
|
||||
Region &select_not_overlapping (const Region &other)
|
||||
|
|
@ -1563,6 +1585,8 @@ private:
|
|||
EdgePairs run_single_polygon_check (db::edge_relation_type rel, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection) const;
|
||||
void select_interacting_generic (const Region &other, int mode, bool touching, bool inverse);
|
||||
Region selected_interacting_generic (const Region &other, int mode, bool touching, bool inverse) const;
|
||||
Region selected_interacting_generic (const Edges &other, bool inverse) const;
|
||||
void select_interacting_generic (const Edges &other, bool inverse);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1312,7 +1312,7 @@ Class<db::Region> decl_Region ("Region",
|
|||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= of merged semantics)\n"
|
||||
) +
|
||||
method ("interacting", &db::Region::selected_interacting,
|
||||
method ("interacting", (db::Region (db::Region::*) (const db::Region &) const) &db::Region::selected_interacting,
|
||||
"@brief Returns the polygons of this region which overlap or touch polygons from the other region\n"
|
||||
"\n"
|
||||
"@args other\n"
|
||||
|
|
@ -1320,7 +1320,7 @@ Class<db::Region> decl_Region ("Region",
|
|||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= of merged semantics)\n"
|
||||
) +
|
||||
method ("not_interacting", &db::Region::selected_not_interacting,
|
||||
method ("not_interacting", (db::Region (db::Region::*) (const db::Region &) const) &db::Region::selected_not_interacting,
|
||||
"@brief Returns the polygons of this region which do not overlap or touch polygons from the other region\n"
|
||||
"\n"
|
||||
"@args other\n"
|
||||
|
|
@ -1328,7 +1328,7 @@ Class<db::Region> decl_Region ("Region",
|
|||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= of merged semantics)\n"
|
||||
) +
|
||||
method ("select_interacting", &db::Region::select_interacting,
|
||||
method ("select_interacting", (db::Region &(db::Region::*) (const db::Region &)) &db::Region::select_interacting,
|
||||
"@brief Selects the polygons from this region which overlap or touch polygons from the other region\n"
|
||||
"\n"
|
||||
"@args other\n"
|
||||
|
|
@ -1336,7 +1336,7 @@ Class<db::Region> decl_Region ("Region",
|
|||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= of merged semantics)\n"
|
||||
) +
|
||||
method ("select_not_interacting", &db::Region::select_not_interacting,
|
||||
method ("select_not_interacting", (db::Region &(db::Region::*) (const db::Region &)) &db::Region::select_not_interacting,
|
||||
"@brief Selects the polygons from this region which do not overlap or touch polygons from the other region\n"
|
||||
"\n"
|
||||
"@args other\n"
|
||||
|
|
@ -1344,6 +1344,46 @@ Class<db::Region> decl_Region ("Region",
|
|||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= of merged semantics)\n"
|
||||
) +
|
||||
method ("interacting", (db::Region (db::Region::*) (const db::Edges &) const) &db::Region::selected_interacting,
|
||||
"@brief Returns the polygons of this region which overlap or touch edges from the edge collection\n"
|
||||
"\n"
|
||||
"@args other\n"
|
||||
"@return A new region containing the polygons overlapping or touching edges from the edge collection\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= of merged semantics)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.25\n"
|
||||
) +
|
||||
method ("not_interacting", (db::Region (db::Region::*) (const db::Edges &) const) &db::Region::selected_not_interacting,
|
||||
"@brief Returns the polygons of this region which do not overlap or touch edges from the edge collection\n"
|
||||
"\n"
|
||||
"@args other\n"
|
||||
"@return A new region containing the polygons not overlapping or touching edges from the edge collection\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= of merged semantics)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.25\n"
|
||||
) +
|
||||
method ("select_interacting", (db::Region &(db::Region::*) (const db::Edges &)) &db::Region::select_interacting,
|
||||
"@brief Selects the polygons from this region which overlap or touch edges from the edge collection\n"
|
||||
"\n"
|
||||
"@args other\n"
|
||||
"@return The region after the polygons have been selected (self)\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= of merged semantics)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.25\n"
|
||||
) +
|
||||
method ("select_not_interacting", (db::Region &(db::Region::*) (const db::Edges &)) &db::Region::select_not_interacting,
|
||||
"@brief Selects the polygons from this region which do not overlap or touch edges from the edge collection\n"
|
||||
"\n"
|
||||
"@args other\n"
|
||||
"@return The region after the polygons have been selected (self)\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= of merged semantics)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.25\n"
|
||||
) +
|
||||
method ("overlapping", &db::Region::selected_overlapping,
|
||||
"@brief Returns the polygons of this region which overlap polygons from the other region\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -1169,3 +1169,62 @@ TEST(29)
|
|||
EXPECT_EQ (b.perimeter (), 8000000000.0);
|
||||
}
|
||||
|
||||
TEST(30a)
|
||||
{
|
||||
db::Region r;
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (20, 20), db::Point (30, 30)))).to_string (), "");
|
||||
r.insert (db::Box (db::Point (0, 0), db::Point (100, 200)));
|
||||
r.insert (db::Box (db::Point (-100, -100), db::Point (0, 0)));
|
||||
r.set_merged_semantics (false);
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (20, 20), db::Point (30, 30)))).to_string (), "(0,0;0,200;100,200;100,0)");
|
||||
EXPECT_EQ (r.selected_not_interacting (db::Edges (db::Edge (db::Point (20, 20), db::Point (30, 30)))).to_string (), "(-100,-100;-100,0;0,0;0,-100)");
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (-20, -20), db::Point (30, 30)))).to_string (), "(0,0;0,200;100,200;100,0);(-100,-100;-100,0;0,0;0,-100)");
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (-200, -200), db::Point (-190, -190)))).to_string (), "");
|
||||
db::Region rr = r;
|
||||
r.select_interacting (db::Edges (db::Edge (db::Point (-20, -20), db::Point (-10, -10))));
|
||||
EXPECT_EQ (r.to_string (), "(-100,-100;-100,0;0,0;0,-100)");
|
||||
rr.select_not_interacting (db::Edges (db::Edge (db::Point (-20, -20), db::Point (-10, -10))));
|
||||
EXPECT_EQ (rr.to_string (), "(0,0;0,200;100,200;100,0)");
|
||||
|
||||
r.clear ();
|
||||
r.insert(db::Box (db::Point (1000, 0), db::Point (6000, 4000)));
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (0, 4000), db::Point (2000, 6000)))).to_string (), "");
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (1000, 4000), db::Point (2000, 6000)))).to_string (), "(1000,0;1000,4000;6000,4000;6000,0)");
|
||||
EXPECT_EQ (db::Edges (db::Edge (db::Point (0, 4000), db::Point (2000, 6000))).selected_interacting (r).to_string (), "");
|
||||
EXPECT_EQ (db::Edges (db::Edge (db::Point (1000, 4000), db::Point (2000, 6000))).selected_interacting (r).to_string (), "(1000,4000;2000,6000)");
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (1000, 4001), db::Point (2000, 6000)))).to_string (), "");
|
||||
EXPECT_EQ (db::Edges (db::Edge (db::Point (1000, 4001), db::Point (2000, 6000))).selected_interacting (r).to_string (), "");
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (1000, 3999), db::Point (1000, 6000)))).to_string (), "(1000,0;1000,4000;6000,4000;6000,0)");
|
||||
EXPECT_EQ (db::Edges (db::Edge (db::Point (1000, 3999), db::Point (1000, 6000))).selected_interacting (r).to_string (), "(1000,3999;1000,6000)");
|
||||
}
|
||||
|
||||
TEST(30b)
|
||||
{
|
||||
db::Region r;
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (20, 20), db::Point (30, 30)))).to_string (), "");
|
||||
r.insert (db::Box (db::Point (0, 0), db::Point (100, 200)));
|
||||
r.insert (db::Box (db::Point (-100, -100), db::Point (0, 0)));
|
||||
r.set_merged_semantics (true);
|
||||
r.set_min_coherence (true);
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (20, 20), db::Point (30, 30)))).to_string (), "(0,0;0,200;100,200;100,0)");
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (-20, -20), db::Point (30, 30)))).to_string (), "(-100,-100;-100,0;0,0;0,-100);(0,0;0,200;100,200;100,0)");
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (-200, -200), db::Point (-190, -190)))).to_string (), "");
|
||||
r.select_interacting (db::Edges (db::Edge (db::Point (-20, -20), db::Point (-10, -10))));
|
||||
EXPECT_EQ (r.to_string (), "(-100,-100;-100,0;0,0;0,-100)");
|
||||
}
|
||||
|
||||
TEST(30c)
|
||||
{
|
||||
db::Region r;
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (20, 20), db::Point (30, 30)))).to_string (), "");
|
||||
r.insert (db::Box (db::Point (0, 0), db::Point (100, 200)));
|
||||
r.insert (db::Box (db::Point (-100, -100), db::Point (0, 0)));
|
||||
r.set_merged_semantics (true);
|
||||
r.set_min_coherence (false);
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (20, 20), db::Point (30, 30)))).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)");
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (-20, -20), db::Point (30, 30)))).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)");
|
||||
EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (-200, -200), db::Point (-190, -190)))).to_string (), "");
|
||||
r.select_interacting (db::Edges (db::Edge (db::Point (-20, -20), db::Point (-10, -10))));
|
||||
EXPECT_EQ (r.to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue