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
|
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
|
// simple polygon binding
|
||||||
|
|
||||||
|
|
@ -245,13 +278,6 @@ struct simple_polygon_defs
|
||||||
return db::interact (*p, spoly);
|
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 ()
|
static gsi::Methods methods ()
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
|
@ -508,7 +534,7 @@ struct simple_polygon_defs
|
||||||
"\n"
|
"\n"
|
||||||
"This method was introduced in version 0.25.\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"
|
"@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 "
|
"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. "
|
"result are smaller polygons of roughly equal number of points and 'less concave' nature. "
|
||||||
|
|
@ -521,6 +547,20 @@ struct simple_polygon_defs
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.25.3."
|
"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,
|
method_ext ("area", &area,
|
||||||
"@brief Gets the area of the polygon\n"
|
"@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."
|
"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);
|
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 ()
|
static gsi::Methods methods ()
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
|
@ -1520,7 +1553,7 @@ struct polygon_defs
|
||||||
"\n"
|
"\n"
|
||||||
"This method was introduced in version 0.25.\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"
|
"@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 "
|
"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. "
|
"result are smaller polygons of roughly equal number of points and 'less concave' nature. "
|
||||||
|
|
@ -1533,6 +1566,20 @@ struct polygon_defs
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.25.3."
|
"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,
|
method_ext ("area", &area,
|
||||||
"@brief Gets the area of the polygon\n"
|
"@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."
|
"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
|
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
|
def test_voidMethodsReturnSelf
|
||||||
|
|
||||||
hull = [ RBA::Point::new(0, 0), RBA::Point::new(6000, 0),
|
hull = [ RBA::Point::new(0, 0), RBA::Point::new(6000, 0),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue