|
1 // geometry.ysl2 |
|
2 // |
|
3 // Geometry (bounding box intersection) definitions |
|
4 |
|
5 // This retrieves geometry obtained through "inkscape -S" |
|
6 // already parsed by python and presented as a list of |
|
7 // <bbox x="0" y="0" w="42" h="42"> |
|
8 const "all_geometry", "ns:GetSVGGeometry()"; |
|
9 const "defs", "//svg:defs/descendant-or-self::svg:*"; |
|
10 const "geometry", "$all_geometry[not(@Id = $defs/@id)]"; |
|
11 |
|
12 // Debug data |
|
13 emit "debug:geometry" { |
|
14 | ID, x, y, w, h |
|
15 foreach "$geometry" |
|
16 | «@Id» «@x» «@y» «@w» «@h» |
|
17 } |
|
18 |
|
19 // Rates 1D intersection of 2 segments A and B |
|
20 // described respectively with a0,a1 and b0,b1 |
|
21 def "func:intersect_1d" { |
|
22 // it is assumed that a1 > a0 and b1 > b0 |
|
23 param "a0"; |
|
24 param "a1"; |
|
25 param "b0"; |
|
26 param "b1"; |
|
27 |
|
28 const "d0", "$a0 >= $b0"; |
|
29 const "d1", "$a1 >= $b1"; |
|
30 choose { |
|
31 when "not($d0) and $d1" |
|
32 // b contained in a |
|
33 // a0<b0 b1<a1 |
|
34 // a +--------+ |
|
35 // b +--+ |
|
36 result "3"; |
|
37 when "$d0 and not($d1)" |
|
38 // a contained in b |
|
39 // b0<a0 a1<b1 |
|
40 // a +--+ |
|
41 // b +--------+ |
|
42 result "2"; |
|
43 when "$d0 and $d1 and $a0 < $b1" |
|
44 // a and b are overlapped |
|
45 // b0<a0<b1<a1 |
|
46 // a +-----+ |
|
47 // b +-----+ |
|
48 result "1"; |
|
49 when "not($d0) and not($d1) and $b0 < $a1" |
|
50 // a and b are overlapped |
|
51 // a0<b0<a1<b1 |
|
52 // a +-----+ |
|
53 // b +-----+ |
|
54 result "1"; |
|
55 // since orientation doesn't matter, |
|
56 // rated same as previous symetrical overlapping |
|
57 otherwise |
|
58 result "0"; /* no intersection*/ |
|
59 } |
|
60 } |
|
61 |
|
62 |
|
63 // Rates intersection A and B areas described with x,y,w and h |
|
64 // attributes passed as $a and $b parameters. |
|
65 // |
|
66 // returns : |
|
67 // 0 - no intersection |
|
68 // .-----. |
|
69 // .-----. | b| |
|
70 // | | | | |
|
71 // | | '-----' |
|
72 // |a | |
|
73 // '-----' |
|
74 // |
|
75 // 1 - overlapping |
|
76 // .-----. |
|
77 // .---|--. b| |
|
78 // | | | | |
|
79 // | '-----' |
|
80 // |a | |
|
81 // '------' |
|
82 // |
|
83 // 2 - overlapping |
|
84 // .-----. |
|
85 // | a | |
|
86 // .---|-----|---. |
|
87 // | '-----' | |
|
88 // | b | |
|
89 // '-------------' |
|
90 // |
|
91 // 3 - overlapping |
|
92 // .-----. |
|
93 // | b | |
|
94 // .---|-----|---. |
|
95 // | '-----' | |
|
96 // | a | |
|
97 // '-------------' |
|
98 // |
|
99 // 4 - a contained in b |
|
100 // .-------------. |
|
101 // | .-----. | |
|
102 // | | a | | |
|
103 // |b '-----' | |
|
104 // '-------------' |
|
105 // |
|
106 // 6 - overlapping |
|
107 // .----. |
|
108 // | b| |
|
109 // .---|----|---. |
|
110 // |a | | | |
|
111 // '---|----|---' |
|
112 // '----' |
|
113 // |
|
114 // 9 - b contained in a |
|
115 // .-------------. |
|
116 // | .-----. | |
|
117 // | | b | | |
|
118 // |a '-----' | |
|
119 // '-------------' |
|
120 // |
|
121 def "func:intersect" { |
|
122 param "a"; |
|
123 param "b"; |
|
124 |
|
125 const "x_intersect", "func:intersect_1d($a/@x, $a/@x+$a/@w, $b/@x, $b/@x+$b/@w)"; |
|
126 |
|
127 choose{ |
|
128 when "$x_intersect != 0"{ |
|
129 const "y_intersect", "func:intersect_1d($a/@y, $a/@y+$a/@h, $b/@y, $b/@y+$b/@h)"; |
|
130 result "$x_intersect * $y_intersect"; |
|
131 } |
|
132 otherwise result "0"; |
|
133 } |
|
134 } |
|
135 |
|
136 const "groups", "/svg:svg | //svg:g"; |
|
137 |
|
138 // return overlapping geometry for a given element |
|
139 // all intersercting element are returned |
|
140 // except groups, that must be contained to be counted in |
|
141 def "func:overlapping_geometry" { |
|
142 param "elt"; |
|
143 const "g", "$geometry[@Id = $elt/@id]"; |
|
144 const "candidates", "$geometry[@Id != $elt/@id]"; |
|
145 result """$candidates[(@Id = $groups/@id and (func:intersect($g, .) = 9)) or |
|
146 (not(@Id = $groups/@id) and (func:intersect($g, .) > 0 ))]"""; |
|
147 } |