svghmi/geometry.ysl2
changeset 3302 c89fc366bebd
parent 3199 1582753e409b
child 3625 bb1eff4091ab
equal deleted inserted replaced
2744:577118ebd179 3302:c89fc366bebd
       
     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 }