edouard@2873: // geometry.ysl2 edouard@2872: // edouard@2873: // Geometry (bounding box intersection) definitions edouard@2873: edouard@2873: // This retrieves geometry obtained through "inkscape -S" edouard@2873: // already parsed by python and presented as a list of edouard@2873: // <bbox x="0" y="0" w="42" h="42"> Edouard@3199: const "all_geometry", "ns:GetSVGGeometry()"; Edouard@3199: const "defs", "//svg:defs/descendant-or-self::svg:*"; Edouard@3199: const "geometry", "$all_geometry[not(@Id = $defs/@id)]"; edouard@2873: edouard@2873: // Debug data edouard@2940: emit "debug:geometry" { edouard@2875: | ID, x, y, w, h Edouard@2879: foreach "$geometry" edouard@2873: | «@Id» «@x» «@y» «@w» «@h» edouard@2873: } Edouard@2779: edouard@2872: // Rates 1D intersection of 2 segments A and B edouard@2872: // described respectively with a0,a1 and b0,b1 edouard@2872: def "func:intersect_1d" { edouard@2872: // it is assumed that a1 > a0 and b1 > b0 edouard@2872: param "a0"; edouard@2872: param "a1"; edouard@2872: param "b0"; edouard@2872: param "b1"; Edouard@2792: edouard@2872: const "d0", "$a0 >= $b0"; edouard@2872: const "d1", "$a1 >= $b1"; edouard@2872: choose { edouard@2872: when "not($d0) and $d1" edouard@2872: // b contained in a edouard@2872: // a0<b0 b1<a1 edouard@2872: // a +--------+ edouard@2872: // b +--+ edouard@2872: result "3"; edouard@2872: when "$d0 and not($d1)" edouard@2872: // a contained in b edouard@2872: // b0<a0 a1<b1 edouard@2872: // a +--+ edouard@2872: // b +--------+ edouard@2872: result "2"; edouard@2872: when "$d0 and $d1 and $a0 < $b1" edouard@2872: // a and b are overlapped edouard@2872: // b0<a0<b1<a1 edouard@2872: // a +-----+ edouard@2872: // b +-----+ edouard@2872: result "1"; edouard@2872: when "not($d0) and not($d1) and $b0 < $a1" edouard@2872: // a and b are overlapped edouard@2872: // a0<b0<a1<b1 edouard@2872: // a +-----+ edouard@2872: // b +-----+ edouard@2872: result "1"; edouard@2872: // since orientation doesn't matter, edouard@2872: // rated same as previous symetrical overlapping edouard@2872: otherwise edouard@2872: result "0"; /* no intersection*/ Edouard@2795: } edouard@2872: } Edouard@2790: Edouard@2843: edouard@2872: // Rates intersection A and B areas described with x,y,w and h edouard@2872: // attributes passed as $a and $b parameters. edouard@2872: // edouard@2872: // returns : edouard@2872: // 0 - no intersection edouard@2872: // .-----. edouard@2872: // .-----. | b| edouard@2872: // | | | | edouard@2872: // | | '-----' edouard@2872: // |a | edouard@2872: // '-----' edouard@2872: // edouard@2872: // 1 - overlapping edouard@2872: // .-----. edouard@2872: // .---|--. b| edouard@2872: // | | | | edouard@2872: // | '-----' edouard@2872: // |a | edouard@2872: // '------' edouard@2872: // edouard@2872: // 2 - overlapping edouard@2872: // .-----. edouard@2872: // | a | edouard@2872: // .---|-----|---. edouard@2872: // | '-----' | edouard@2872: // | b | edouard@2872: // '-------------' edouard@2872: // edouard@2872: // 3 - overlapping edouard@2872: // .-----. edouard@2872: // | b | edouard@2872: // .---|-----|---. edouard@2872: // | '-----' | edouard@2872: // | a | edouard@2872: // '-------------' edouard@2872: // edouard@2872: // 4 - a contained in b edouard@2872: // .-------------. edouard@2872: // | .-----. | edouard@2872: // | | a | | edouard@2872: // |b '-----' | edouard@2872: // '-------------' edouard@2872: // edouard@2872: // 6 - overlapping edouard@2872: // .----. edouard@2872: // | b| edouard@2872: // .---|----|---. edouard@2872: // |a | | | edouard@2872: // '---|----|---' edouard@2872: // '----' edouard@2872: // edouard@2872: // 9 - b contained in a edouard@2872: // .-------------. edouard@2872: // | .-----. | edouard@2872: // | | b | | edouard@2872: // |a '-----' | edouard@2872: // '-------------' edouard@2872: // edouard@2872: def "func:intersect" { edouard@2872: param "a"; edouard@2872: param "b"; edouard@2872: edouard@2872: const "x_intersect", "func:intersect_1d($a/@x, $a/@x+$a/@w, $b/@x, $b/@x+$b/@w)"; edouard@2872: edouard@2872: choose{ edouard@2872: when "$x_intersect != 0"{ edouard@2872: const "y_intersect", "func:intersect_1d($a/@y, $a/@y+$a/@h, $b/@y, $b/@y+$b/@h)"; edouard@2872: result "$x_intersect * $y_intersect"; Edouard@2844: } edouard@2872: otherwise result "0"; Edouard@2808: } Edouard@2753: } edouard@2873: edouard@3165: const "groups", "/svg:svg | //svg:g"; edouard@3165: edouard@2873: // return overlapping geometry for a given element edouard@2873: // all intersercting element are returned edouard@2873: // except groups, that must be contained to be counted in edouard@2873: def "func:overlapping_geometry" { edouard@2873: param "elt"; edouard@2873: const "g", "$geometry[@Id = $elt/@id]"; edouard@2873: const "candidates", "$geometry[@Id != $elt/@id]"; edouard@2873: result """$candidates[(@Id = $groups/@id and (func:intersect($g, .) = 9)) or edouard@2873: (not(@Id = $groups/@id) and (func:intersect($g, .) > 0 ))]"""; edouard@2873: }