mirror of https://github.com/KLayout/klayout.git
Polygon#break, DPolygon#break, SimplPolygon#break, DSimplePolygon#break
This commit is contained in:
parent
c2187e0bf0
commit
a431f70ad4
|
|
@ -31,6 +31,39 @@
|
|||
namespace gsi
|
||||
{
|
||||
|
||||
template <class C>
|
||||
static std::vector<C> split_poly (const C *p)
|
||||
{
|
||||
std::vector<C> parts;
|
||||
db::split_polygon (*p, parts);
|
||||
return parts;
|
||||
}
|
||||
|
||||
template <class C>
|
||||
static void break_polygon (const C &poly, size_t max_vertex_count, double max_area_ratio, std::vector<C> &result)
|
||||
{
|
||||
if ((max_vertex_count > 0 && poly.vertices () > max_vertex_count) ||
|
||||
(max_area_ratio > 0 && poly.area_ratio () > max_area_ratio)) {
|
||||
|
||||
std::vector<C> split_polygons;
|
||||
db::split_polygon (poly, split_polygons);
|
||||
for (auto p = split_polygons.begin (); p != split_polygons.end (); ++p) {
|
||||
break_polygon (*p, max_vertex_count, max_area_ratio, result);
|
||||
}
|
||||
|
||||
} else {
|
||||
result.push_back (poly);
|
||||
}
|
||||
}
|
||||
|
||||
template <class C>
|
||||
static std::vector<C> break_poly (const C *p, size_t max_vertex_count, double max_area_ratio)
|
||||
{
|
||||
std::vector<C> parts;
|
||||
break_polygon (*p, max_vertex_count, max_area_ratio, parts);
|
||||
return parts;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// simple polygon binding
|
||||
|
||||
|
|
@ -245,13 +278,6 @@ struct simple_polygon_defs
|
|||
return db::interact (*p, spoly);
|
||||
}
|
||||
|
||||
static std::vector<C> split_poly (const C *p)
|
||||
{
|
||||
std::vector<C> parts;
|
||||
db::split_polygon (*p, parts);
|
||||
return parts;
|
||||
}
|
||||
|
||||
static gsi::Methods methods ()
|
||||
{
|
||||
return
|
||||
|
|
@ -508,7 +534,7 @@ struct simple_polygon_defs
|
|||
"\n"
|
||||
"This method was introduced in version 0.25.\n"
|
||||
) +
|
||||
method_ext ("split", &split_poly,
|
||||
method_ext ("split", &split_poly<C>,
|
||||
"@brief Splits the polygon into two or more parts\n"
|
||||
"This method will break the polygon into parts. The exact breaking algorithm is unspecified, the "
|
||||
"result are smaller polygons of roughly equal number of points and 'less concave' nature. "
|
||||
|
|
@ -521,6 +547,20 @@ struct simple_polygon_defs
|
|||
"\n"
|
||||
"This method has been introduced in version 0.25.3."
|
||||
) +
|
||||
method_ext ("break", &break_poly<C>, gsi::arg ("max_vertex_count"), gsi::arg ("max_area_ratio"),
|
||||
"@brief Splits the polygon into parts with a maximum vertex count and area ratio\n"
|
||||
"The area ratio is the ratio between the bounding box area and the polygon area. Higher values "
|
||||
"mean more 'skinny' polygons.\n"
|
||||
"\n"
|
||||
"This method will split the input polygon into pieces having a maximum of 'max_vertex_count' vertices "
|
||||
"and an area ratio less than 'max_area_ratio'. 'max_vertex_count' can be zero. In this case the "
|
||||
"limit is ignored. Also 'max_area_ratio' can be zero, in which case it is ignored as well.\n"
|
||||
"\n"
|
||||
"The method of splitting is unspecified. The algorithm will apply 'split' recursively until the "
|
||||
"parts satisfy the limits.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29."
|
||||
) +
|
||||
method_ext ("area", &area,
|
||||
"@brief Gets the area of the polygon\n"
|
||||
"The area is correct only if the polygon is not self-overlapping and the polygon is oriented clockwise."
|
||||
|
|
@ -1098,13 +1138,6 @@ struct polygon_defs
|
|||
return db::interact (*p, spoly);
|
||||
}
|
||||
|
||||
static std::vector<C> split_spoly (const C *p)
|
||||
{
|
||||
std::vector<C> parts;
|
||||
db::split_polygon (*p, parts);
|
||||
return parts;
|
||||
}
|
||||
|
||||
static gsi::Methods methods ()
|
||||
{
|
||||
return
|
||||
|
|
@ -1520,7 +1553,7 @@ struct polygon_defs
|
|||
"\n"
|
||||
"This method was introduced in version 0.25.\n"
|
||||
) +
|
||||
method_ext ("split", &split_spoly,
|
||||
method_ext ("split", &split_poly<C>,
|
||||
"@brief Splits the polygon into two or more parts\n"
|
||||
"This method will break the polygon into parts. The exact breaking algorithm is unspecified, the "
|
||||
"result are smaller polygons of roughly equal number of points and 'less concave' nature. "
|
||||
|
|
@ -1533,6 +1566,20 @@ struct polygon_defs
|
|||
"\n"
|
||||
"This method has been introduced in version 0.25.3."
|
||||
) +
|
||||
method_ext ("break", &break_poly<C>, gsi::arg ("max_vertex_count"), gsi::arg ("max_area_ratio"),
|
||||
"@brief Splits the polygon into parts with a maximum vertex count and area ratio\n"
|
||||
"The area ratio is the ratio between the bounding box area and the polygon area. Higher values "
|
||||
"mean more 'skinny' polygons.\n"
|
||||
"\n"
|
||||
"This method will split the input polygon into pieces having a maximum of 'max_vertex_count' vertices "
|
||||
"and an area ratio less than 'max_area_ratio'. 'max_vertex_count' can be zero. In this case the "
|
||||
"limit is ignored. Also 'max_area_ratio' can be zero, in which case it is ignored as well.\n"
|
||||
"\n"
|
||||
"The method of splitting is unspecified. The algorithm will apply 'split' recursively until the "
|
||||
"parts satisfy the limits.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29."
|
||||
) +
|
||||
method_ext ("area", &area,
|
||||
"@brief Gets the area of the polygon\n"
|
||||
"The area is correct only if the polygon is not self-overlapping and the polygon is oriented clockwise."
|
||||
|
|
|
|||
|
|
@ -821,6 +821,54 @@ class DBPolygon_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def test_breakPolygon
|
||||
|
||||
pts = []
|
||||
pts << RBA::Point::new(0, 0)
|
||||
pts << RBA::Point::new(0, 1000)
|
||||
pts << RBA::Point::new(100, 1000)
|
||||
pts << RBA::Point::new(100, 100)
|
||||
pts << RBA::Point::new(1000, 100)
|
||||
pts << RBA::Point::new(1000, 0)
|
||||
|
||||
split = RBA::Polygon::new(pts).break(4, 0)
|
||||
assert_equal(split.collect { |p| p.to_s }.join(";"), "(0,0;0,100;1000,100;1000,0);(0,100;0,1000;100,1000;100,100)")
|
||||
split = RBA::Polygon::new(pts).break(0, 2.0)
|
||||
assert_equal(split.collect { |p| p.to_s }.join(";"), "(0,0;0,100;1000,100;1000,0);(0,100;0,1000;100,1000;100,100)")
|
||||
split = RBA::Polygon::new(pts).break(0, 0)
|
||||
assert_equal(split.collect { |p| p.to_s }.join(";"), "(0,0;0,1000;100,1000;100,100;1000,100;1000,0)")
|
||||
|
||||
split = RBA::SimplePolygon::new(pts).break(4, 0)
|
||||
assert_equal(split.collect { |p| p.to_s }.join(";"), "(0,0;0,100;1000,100;1000,0);(0,100;0,1000;100,1000;100,100)")
|
||||
split = RBA::SimplePolygon::new(pts).break(0, 2.0)
|
||||
assert_equal(split.collect { |p| p.to_s }.join(";"), "(0,0;0,100;1000,100;1000,0);(0,100;0,1000;100,1000;100,100)")
|
||||
split = RBA::SimplePolygon::new(pts).break(0, 0)
|
||||
assert_equal(split.collect { |p| p.to_s }.join(";"), "(0,0;0,1000;100,1000;100,100;1000,100;1000,0)")
|
||||
|
||||
pts = []
|
||||
pts << RBA::DPoint::new(0, 0)
|
||||
pts << RBA::DPoint::new(0, 1000)
|
||||
pts << RBA::DPoint::new(100, 1000)
|
||||
pts << RBA::DPoint::new(100, 100)
|
||||
pts << RBA::DPoint::new(1000, 100)
|
||||
pts << RBA::DPoint::new(1000, 0)
|
||||
|
||||
split = RBA::DPolygon::new(pts).break(4, 0)
|
||||
assert_equal(split.collect { |p| p.to_s }.join(";"), "(0,0;0,100;1000,100;1000,0);(0,100;0,1000;100,1000;100,100)")
|
||||
split = RBA::DPolygon::new(pts).break(0, 2.0)
|
||||
assert_equal(split.collect { |p| p.to_s }.join(";"), "(0,0;0,100;1000,100;1000,0);(0,100;0,1000;100,1000;100,100)")
|
||||
split = RBA::DPolygon::new(pts).break(0, 0)
|
||||
assert_equal(split.collect { |p| p.to_s }.join(";"), "(0,0;0,1000;100,1000;100,100;1000,100;1000,0)")
|
||||
|
||||
split = RBA::DSimplePolygon::new(pts).break(4, 0)
|
||||
assert_equal(split.collect { |p| p.to_s }.join(";"), "(0,0;0,100;1000,100;1000,0);(0,100;0,1000;100,1000;100,100)")
|
||||
split = RBA::DSimplePolygon::new(pts).break(0, 2.0)
|
||||
assert_equal(split.collect { |p| p.to_s }.join(";"), "(0,0;0,100;1000,100;1000,0);(0,100;0,1000;100,1000;100,100)")
|
||||
split = RBA::DSimplePolygon::new(pts).break(0, 0)
|
||||
assert_equal(split.collect { |p| p.to_s }.join(";"), "(0,0;0,1000;100,1000;100,100;1000,100;1000,0)")
|
||||
|
||||
end
|
||||
|
||||
def test_voidMethodsReturnSelf
|
||||
|
||||
hull = [ RBA::Point::new(0, 0), RBA::Point::new(6000, 0),
|
||||
|
|
|
|||
Loading…
Reference in New Issue