--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/geometry.ysl2 Tue Mar 17 07:39:50 2020 +0100
@@ -0,0 +1,145 @@
+// geometry.ysl2
+//
+// Geometry (bounding box intersection) definitions
+
+// This retrieves geometry obtained through "inkscape -S"
+// already parsed by python and presented as a list of
+// <bbox x="0" y="0" w="42" h="42">
+const "geometry", "ns:GetSVGGeometry()";
+
+// Debug data
+function "debug_geometry" {
+ | GEOMETRY : ID, x, y, w, h
+ foreach "$geometry[@Id = $hmi_elements/@id]"
+ | «@Id» «@x» «@y» «@w» «@h»
+}
+!debug_output_calls.append("debug_geometry")
+
+// Rates 1D intersection of 2 segments A and B
+// described respectively with a0,a1 and b0,b1
+def "func:intersect_1d" {
+ // it is assumed that a1 > a0 and b1 > b0
+ param "a0";
+ param "a1";
+ param "b0";
+ param "b1";
+
+ const "d0", "$a0 >= $b0";
+ const "d1", "$a1 >= $b1";
+ choose {
+ when "not($d0) and $d1"
+ // b contained in a
+ // a0<b0 b1<a1
+ // a +--------+
+ // b +--+
+ result "3";
+ when "$d0 and not($d1)"
+ // a contained in b
+ // b0<a0 a1<b1
+ // a +--+
+ // b +--------+
+ result "2";
+ when "$d0 and $d1 and $a0 < $b1"
+ // a and b are overlapped
+ // b0<a0<b1<a1
+ // a +-----+
+ // b +-----+
+ result "1";
+ when "not($d0) and not($d1) and $b0 < $a1"
+ // a and b are overlapped
+ // a0<b0<a1<b1
+ // a +-----+
+ // b +-----+
+ result "1";
+ // since orientation doesn't matter,
+ // rated same as previous symetrical overlapping
+ otherwise
+ result "0"; /* no intersection*/
+ }
+}
+
+
+// Rates intersection A and B areas described with x,y,w and h
+// attributes passed as $a and $b parameters.
+//
+// returns :
+// 0 - no intersection
+// .-----.
+// .-----. | b|
+// | | | |
+// | | '-----'
+// |a |
+// '-----'
+//
+// 1 - overlapping
+// .-----.
+// .---|--. b|
+// | | | |
+// | '-----'
+// |a |
+// '------'
+//
+// 2 - overlapping
+// .-----.
+// | a |
+// .---|-----|---.
+// | '-----' |
+// | b |
+// '-------------'
+//
+// 3 - overlapping
+// .-----.
+// | b |
+// .---|-----|---.
+// | '-----' |
+// | a |
+// '-------------'
+//
+// 4 - a contained in b
+// .-------------.
+// | .-----. |
+// | | a | |
+// |b '-----' |
+// '-------------'
+//
+// 6 - overlapping
+// .----.
+// | b|
+// .---|----|---.
+// |a | | |
+// '---|----|---'
+// '----'
+//
+// 9 - b contained in a
+// .-------------.
+// | .-----. |
+// | | b | |
+// |a '-----' |
+// '-------------'
+//
+def "func:intersect" {
+ param "a";
+ param "b";
+
+ const "x_intersect", "func:intersect_1d($a/@x, $a/@x+$a/@w, $b/@x, $b/@x+$b/@w)";
+
+ choose{
+ when "$x_intersect != 0"{
+ const "y_intersect", "func:intersect_1d($a/@y, $a/@y+$a/@h, $b/@y, $b/@y+$b/@h)";
+ result "$x_intersect * $y_intersect";
+ }
+ otherwise result "0";
+ }
+}
+
+// return overlapping geometry for a given element
+// all intersercting element are returned
+// except groups, that must be contained to be counted in
+def "func:overlapping_geometry" {
+ param "elt";
+ const "groups", "/svg:svg | //svg:g";
+ const "g", "$geometry[@Id = $elt/@id]";
+ const "candidates", "$geometry[@Id != $elt/@id]";
+ result """$candidates[(@Id = $groups/@id and (func:intersect($g, .) = 9)) or
+ (not(@Id = $groups/@id) and (func:intersect($g, .) > 0 ))]""";
+}