Added tests, documentation, doc bug fixes for angle-class edge selectors

This commit is contained in:
Matthias Koefferlein 2022-11-12 18:16:57 +01:00
parent 4467089f2a
commit 30ab1a13ca
6 changed files with 120 additions and 11 deletions

View File

@ -676,7 +676,15 @@ Class<db::EdgePairs> decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
"This will filter edge pairs with at least one horizontal edge:\n"
"\n"
"@code\n"
"horizontal = edge_pairs.with_orientation(0, false)\n"
"horizontal = edge_pairs.with_angle(0, false)\n"
"@/code\n"
"\n"
"Note that the inverse @b result @/b of \\with_angle is delivered by \\with_angle_both with the inverse flag set as edge pairs are unselected when both edges fail to meet the criterion.\n"
"I.e\n"
"\n"
"@code\n"
"result = edge_pairs.with_angle(0, false)\n"
"others = edge_pairs.with_angle_both(0, true)\n"
"@/code\n"
"\n"
"This method has been added in version 0.27.1.\n"
@ -690,6 +698,14 @@ Class<db::EdgePairs> decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
"With \"include_min_angle\" set to true (the default), the minimum angle is included in the criterion while with false, the "
"minimum angle itself is not included. Same for \"include_max_angle\" where the default is false, meaning the maximum angle is not included in the range.\n"
"\n"
"Note that the inverse @b result @/b of \\with_angle is delivered by \\with_angle_both with the inverse flag set as edge pairs are unselected when both edges fail to meet the criterion.\n"
"I.e\n"
"\n"
"@code\n"
"result = edge_pairs.with_angle(0, 45, false)\n"
"others = edge_pairs.with_angle_both(0, 45, true)\n"
"@/code\n"
"\n"
"This method has been added in version 0.27.1.\n"
) +
method_ext ("with_angle", with_angle3, gsi::arg ("type"), gsi::arg ("inverse"),
@ -699,7 +715,15 @@ Class<db::EdgePairs> decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
"edge pairs not fulfilling this criterion are returned.\n"
"\n"
"This version allows specifying an edge type instead of an angle. Edge types include multiple distinct orientations "
"and are specified using one of the \\Edges#OrthoEdges, \\Edges#DiagonalEgdes or \\Edges#OrthoDiagonalEdges types.\n"
"and are specified using one of the \\Edges#OrthoEdges, \\Edges#DiagonalEdges or \\Edges#OrthoDiagonalEdges types.\n"
"\n"
"Note that the inverse @b result @/b of \\with_angle is delivered by \\with_angle_both with the inverse flag set as edge pairs are unselected when both edges fail to meet the criterion.\n"
"I.e\n"
"\n"
"@code\n"
"result = edge_pairs.with_angle(RBA::Edges::Ortho, false)\n"
"others = edge_pairs.with_angle_both(RBA::Edges::Ortho, true)\n"
"@/code\n"
"\n"
"This method has been added in version 0.28.\n"
) +
@ -712,7 +736,15 @@ Class<db::EdgePairs> decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
"This will filter edge pairs with at least one horizontal edge:\n"
"\n"
"@code\n"
"horizontal = edge_pairs.with_orientation(0, false)\n"
"horizontal = edge_pairs.with_angle_both(0, false)\n"
"@/code\n"
"\n"
"Note that the inverse @b result @/b of \\with_angle_both is delivered by \\with_angle with the inverse flag set as edge pairs are unselected when one edge fails to meet the criterion.\n"
"I.e\n"
"\n"
"@code\n"
"result = edge_pairs.with_angle_both(0, false)\n"
"others = edge_pairs.with_angle(0, true)\n"
"@/code\n"
"\n"
"This method has been added in version 0.27.1.\n"
@ -726,16 +758,32 @@ Class<db::EdgePairs> decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
"With \"include_min_angle\" set to true (the default), the minimum angle is included in the criterion while with false, the "
"minimum angle itself is not included. Same for \"include_max_angle\" where the default is false, meaning the maximum angle is not included in the range.\n"
"\n"
"Note that the inverse @b result @/b of \\with_angle_both is delivered by \\with_angle with the inverse flag set as edge pairs are unselected when one edge fails to meet the criterion.\n"
"I.e\n"
"\n"
"@code\n"
"result = edge_pairs.with_angle_both(0, 45, false)\n"
"others = edge_pairs.with_angle(0, 45, true)\n"
"@/code\n"
"\n"
"This method has been added in version 0.27.1.\n"
) +
method_ext ("with_angle_both", with_angle_both3, gsi::arg ("type"), gsi::arg ("inverse"),
"@brief Filter the edge pairs by orientation of their edges\n"
"Filters the edge pairs in the edge pair collection by orientation. If \"inverse\" is false, only "
"edge pairs with both edges having an angle of the given type are returned. If \"inverse\" is true, "
"edge pairs not fulfilling this criterion are returned.\n"
"edge pairs not fulfilling this criterion for both edges are returned.\n"
"\n"
"This version allows specifying an edge type instead of an angle. Edge types include multiple distinct orientations "
"and are specified using one of the \\Edges#OrthoEdges, \\Edges#DiagonalEgdes or \\Edges#OrthoDiagonalEdges types.\n"
"and are specified using one of the \\Edges#OrthoEdges, \\Edges#DiagonalEdges or \\Edges#OrthoDiagonalEdges types.\n"
"\n"
"Note that the inverse @b result @/b of \\with_angle_both is delivered by \\with_angle with the inverse flag set as edge pairs are unselected when one edge fails to meet the criterion.\n"
"I.e\n"
"\n"
"@code\n"
"result = edge_pairs.with_angle_both(RBA::Edges::Ortho, false)\n"
"others = edge_pairs.with_angle(RBA::Edges::Ortho, true)\n"
"@/code\n"
"\n"
"This method has been added in version 0.28.\n"
) +

View File

@ -639,7 +639,7 @@ Class<db::Edges> decl_Edges (decl_dbShapeCollection, "db", "Edges",
"This will select horizontal edges:\n"
"\n"
"@code\n"
"horizontal = edges.with_orientation(0, false)\n"
"horizontal = edges.with_angle(0, false)\n"
"@/code\n"
) +
method_ext ("with_angle", with_angle2, gsi::arg ("min_angle"), gsi::arg ("max_angle"), gsi::arg ("inverse"), gsi::arg ("include_min_angle", true), gsi::arg ("include_max_angle", false),
@ -661,7 +661,7 @@ Class<db::Edges> decl_Edges (decl_dbShapeCollection, "db", "Edges",
"edges which do not conform to this criterion are returned.\n"
"\n"
"This version allows specifying an edge type instead of an angle. Edge types include multiple distinct orientations "
"and are specified using one of the \\OrthoEdges, \\DiagonalEgdes or \\OrthoDiagonalEdges types.\n"
"and are specified using one of the \\OrthoEdges, \\DiagonalEdges or \\OrthoDiagonalEdges types.\n"
"\n"
"This method has been added in version 0.28.\n"
) +

View File

@ -3290,7 +3290,10 @@ Shielding is enabled by default, but can be switched off with the "transparent"
<li><tt>layer.with_angle(min .. max)</tt></li>
<li><tt>layer.with_angle(value)</tt></li>
<li><tt>layer.with_angle(min, max)</tt></li>
<li><tt>edge_pair_layer.with_angle(min, max [, both])</tt></li>
<li><tt>layer.with_angle(ortho)</tt></li>
<li><tt>layer.with_angle(diagonal)</tt></li>
<li><tt>layer.with_angle(diagonal_only)</tt></li>
<li><tt>edge_pair_layer.with_angle(... [, both])</tt></li>
</ul>
<p>
When called on an edge layer, the method selects edges by their angle,
@ -3303,7 +3306,7 @@ an angle of 90 degee. The angle range is from -90 (exclusive) to 90 degree (incl
The first version of this method selects
edges with a angle larger or equal to min and less than max (but not equal).
The second version selects edges with exactly the given angle. The third
version is identical to the first one.
version is identical to the first one.
</p><p>
When called on an edge pair layer, this method selects edge pairs with one or both edges
meeting the angle criterion. In this case an additional argument is accepted which can be
@ -3320,6 +3323,10 @@ ep2 = edge_pairs.with_angle(90, both)
</pre>
</p><p>
A method delivering all objects not matching the angle criterion is <a href="#without_angle">without_angle</a>.
Note that for edge pairs, in order to get the inverse result, you have to add or drop "both"
on <a href="#without_angle">without_angle</a>. This is because <a href="#without_angle">without_angle</a> without both returns edge pairs where
one edge does not match the criterion. The logical opposite of "one edge matches" however is
"both edges do not match".
</p><p>
The following images demonstrate some use cases of <a href="#with_angle">with_angle</a> and <a href="#without_angle:">without_angle:</a>
</p><p>
@ -3334,6 +3341,17 @@ The following images demonstrate some use cases of <a href="#with_angle">with_an
</tr>
</table>
</p><p>
Specifying "ortho", "diagonal" or "diagonal_only" instead of the angle values will select
0 and 90 degree edges (ortho), -45 and 45 degree edges (diagonal_only) and both types (diagonal).
This simplifies the implementation of selectors for manhattan or half-manhattan features:
</p><p>
<pre>
ortho_edges = edges.with_angle(ortho)
# which is equivalent to, but more efficient as:
ortho_edges = edges.with_angle(0) + edges.with_angle(90)
</pre>
</p><p>
Note that in former versions, with_angle could be used on polygon layers selecting corners with specific angles.
This feature has been deprecated. Use <a href="#corners">corners</a> instead.
</p>
@ -3663,12 +3681,17 @@ This method is available for polygon layers only.
<li><tt>layer.without_angle(min .. max)</tt></li>
<li><tt>layer.without_angle(value)</tt></li>
<li><tt>layer.without_angle(min, max)</tt></li>
<li><tt>edge_pair_layer.without_angle(min, max [, both])</tt></li>
<li><tt>layer.without_angle(ortho)</tt></li>
<li><tt>layer.without_angle(diagonal)</tt></li>
<li><tt>layer.without_angle(diagonal_only)</tt></li>
<li><tt>edge_pair_layer.without_angle(... [, both])</tt></li>
</ul>
<p>
The method basically is the inverse of <a href="#with_angle">with_angle</a>. It selects all edges
of the edge layer or corners of the polygons which do not have the given angle (second form) or whose angle
is not inside the given interval (first and third form). When called on edge pairs, it selects
is not inside the given interval (first and third form) or of the given type (other forms).
</p><p>
When called on edge pairs, it selects
edge pairs by the angles of their edges.
</p><p>
A note on the "both" modifier (without_angle called on edge pairs): "both" means that

View File

@ -896,6 +896,10 @@ CODE
# @/code
#
# A method delivering all objects not matching the angle criterion is \without_angle.
# Note that for edge pairs, in order to get the inverse result, you have to add or drop "both"
# on \without_angle. This is because \without_angle without both returns edge pairs where
# one edge does not match the criterion. The logical opposite of "one edge matches" however is
# "both edges do not match".
#
# The following images demonstrate some use cases of \with_angle and \without_angle:
#

View File

@ -303,6 +303,27 @@ class DBEdgePairs_TestClass < TestBase
assert_equal(r1.with_internal_angle(0, 45, false, true, true).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(20,10;30,0)")
assert_equal(r1.with_internal_angle(0, 45, true, true, true).to_s, "")
ep1 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(10, 0, 20, 0))
ep2 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(10, 0, 20, 10))
ep3 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 20), RBA::Edge::new(10, 20, 10, 0))
ep4 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(10, 0, 15, 10))
r = RBA::EdgePairs::new([ ep1, ep2, ep3, ep4 ])
assert_equal(r.with_angle(RBA::Edges::OrthoEdges, false).to_s, "(0,0;0,10)/(10,0;20,0);(0,0;0,10)/(10,0;20,10);(0,0;0,20)/(10,20;10,0);(0,0;0,10)/(10,0;15,10)")
assert_equal(r.with_angle(RBA::Edges::OrthoEdges, true).to_s, "(0,0;0,10)/(10,0;20,10);(0,0;0,10)/(10,0;15,10)")
assert_equal(r.with_angle(RBA::Edges::DiagonalEdges, false).to_s, "(0,0;0,10)/(10,0;20,10)")
assert_equal(r.with_angle(RBA::Edges::DiagonalEdges, true).to_s, "(0,0;0,10)/(10,0;20,0);(0,0;0,10)/(10,0;20,10);(0,0;0,20)/(10,20;10,0);(0,0;0,10)/(10,0;15,10)")
assert_equal(r.with_angle(RBA::Edges::OrthoDiagonalEdges, false).to_s, "(0,0;0,10)/(10,0;20,0);(0,0;0,10)/(10,0;20,10);(0,0;0,20)/(10,20;10,0);(0,0;0,10)/(10,0;15,10)")
assert_equal(r.with_angle(RBA::Edges::OrthoDiagonalEdges, true).to_s, "(0,0;0,10)/(10,0;15,10)")
assert_equal(r.with_angle_both(RBA::Edges::OrthoEdges, false).to_s, "(0,0;0,10)/(10,0;20,0);(0,0;0,20)/(10,20;10,0)")
assert_equal(r.with_angle_both(RBA::Edges::OrthoEdges, true).to_s, "")
assert_equal(r.with_angle_both(RBA::Edges::DiagonalEdges, false).to_s, "")
assert_equal(r.with_angle_both(RBA::Edges::DiagonalEdges, true).to_s, "(0,0;0,10)/(10,0;20,0);(0,0;0,20)/(10,20;10,0);(0,0;0,10)/(10,0;15,10)")
assert_equal(r.with_angle_both(RBA::Edges::OrthoDiagonalEdges, false).to_s, "(0,0;0,10)/(10,0;20,0);(0,0;0,10)/(10,0;20,10);(0,0;0,20)/(10,20;10,0)")
assert_equal(r.with_angle_both(RBA::Edges::OrthoDiagonalEdges, true).to_s, "")
end
end

View File

@ -474,6 +474,19 @@ class DBEdges_TestClass < TestBase
assert_equal(r.with_length(100, 200, true).to_s, "(100,0;100,50)")
assert_equal(r.with_length(nil, 100, false).to_s, "(100,0;100,50)")
r = RBA::Edges::new
r.insert(RBA::Edge::new(0, 0, 100, 0))
r.insert(RBA::Edge::new(100, 0, 100, 50))
r.insert(RBA::Edge::new(0, 0, 100, 100))
r.insert(RBA::Edge::new(0, 0, 100, -100))
r.insert(RBA::Edge::new(0, 0, 100, 120))
assert_equal(r.with_angle(RBA::Edges::OrthoEdges, false).to_s, "(0,0;100,0);(100,0;100,50)")
assert_equal(r.with_angle(RBA::Edges::OrthoEdges, true).to_s, "(0,0;100,100);(0,0;100,-100);(0,0;100,120)")
assert_equal(r.with_angle(RBA::Edges::DiagonalEdges, false).to_s, "(0,0;100,100);(0,0;100,-100)")
assert_equal(r.with_angle(RBA::Edges::DiagonalEdges, true).to_s, "(0,0;100,0);(100,0;100,50);(0,0;100,120)")
assert_equal(r.with_angle(RBA::Edges::OrthoDiagonalEdges, false).to_s, "(0,0;100,0);(100,0;100,50);(0,0;100,100);(0,0;100,-100)")
assert_equal(r.with_angle(RBA::Edges::OrthoDiagonalEdges, true).to_s, "(0,0;100,120)")
end
# interact