Chapitre 11. SVG

SVG est un dialecte de XML pour le dessin vectoriel. Ce format permet de définir les éléments graphiques de manière standard.

11.1. Un premier exemple

Rendu du document ci-dessous

Figure 11.1. Rendu du document ci-dessous


<?xml version="1.0" encoding="iso-8859-1" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
     "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" width="200" height="100"
     xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink">
 <defs>
   <path id="textpath"
      d="M 15,80 C 35,65 40,65 50,65 C 60,65 80,75 95,75 
         C 110,75 135,60 150,60 C 165,60 170,60 185,65"
      style="fill:none;stroke:black;" />
 </defs>
 <text style="font-family:Verdana; font-size:28; 
              font-weight:bold; fill:red">
   <textPath xlink:href="#textpath">
     Hello, SVG!
   </textPath>
 </text>
 <use xlink:href="#textpath" y="10"/>
</svg>

11.2. Éléments de dessins

11.2.1. Formes élémentaires

ÉlémentRendu

Ligne

<line x1=... y1=... x2=... y2=... />

Rectangle

<rect x=... y=... width=... height=... />

Ellipse

<ellipse cx=... cy=... rx=... ry=... />

Ligne polygonale

<polyline points="x1 y1 x2 y2 x3 y3 ..."/>

Ligne polygonale fermée

<polygon points="x1 y1 x2 y2 x3 y3 ..."/>

11.2.2. Chemins

ÉlémentRendu

Point de départ

<path d="M x1 y1"/>

Ligne horizontale

<path d="M x1 y1 H x2"/>

Ligne verticale

<path d="M x1 y1 V y2"/>

Ligne

<path d="M x1 y1 L x2 y2"/>

Courbe de Bézier quadratique

<path d="M x1 y1 Q cx cy x2 y2"/>

Courbe de Bézier quadratique avec partage de point de contrôle

<path d="M x1 y1 Q cx cy x2 y2 T x3 y3"/>

Courbe de Bézier cubique

<path d="M x1 y1 C cx1 cy1 cx2 cy2 x2 y2"/>

Courbe de Bézier cubique avec partage de point de contrôle

<path d="M x1 y1 C cx1 cy1 cx2 cy2 x2 y2 S cx3 cy3 x3 y3"/>

Fermeture du chemin par une ligne

<path d="M x1 y1 Q cx cy x2 y2 Z"/>

Pour une introduction aux courbes de Bezier, on peut se réferer à cette partie.

11.2.3. Remplissage

ÉlémentRendu (PNG)

Règle evenodd

<path d="..." fill="evenodd"/>

Règle nonzero

<path d="..." fill="nonzero"/>

11.3. Transformations

L'élément g permet de grouper plusieurs éléments graphiques. Il est ainsi possible d'associer simlutanément à plusieurs éléments des règles de style communes.

L'élément g permet aussi d'appliquer des transformations affines sur les éléments graphiques. L'attribut transform de l'élément g contient une suite de transformations appliquées successivments. Les transformations possibles sont les suivantes.

TransformationAction
translate(dx,dy) Translation (déplacement)
scale(x) ou scale(x,y) Dilatation
rotate(a) ou scale(a,cx,cy) Rotation
skewX(x) et skewY(y) Inclinaisons

11.4. Indications de style

11.4.1. Attribut style

<svg width="200" height="100">
  <rect x="10" y="10" width="180" height="80" style="stroke:black;fill:none"/>
  <ellipse cx="100" cy="50" rx="90" ry="40" style="stroke:black;fill:red"/>
  <ellipse class="circle" cx="100" cy="50" rx="40" ry="40"/>
</svg>

11.4.2. Attributs spécifiques

<svg width="200" height="100">
  <rect x="10" y="10" width="180" height="80" stroke="black" fill="none"/>
  <ellipse cx="100" cy="50" rx="90" ry="40" stroke="black"/>
  <ellipse class="circle" cx="100" cy="50" rx="40" ry="40" fill="red"/>
</svg>

11.4.3. Élément style

<svg width="200" height="100">
  <style type="text/css">
    rect { stroke: red}
    ellipse { fill: red }
    ellipse.circle { fill: white }
  </style>
  <rect x="10" y="10" width="180" height="80"/>
  <ellipse cx="100" cy="50" rx="90" ry="40"/>
  <ellipse class="circle" cx="100" cy="50" rx="40" ry="40"/>
</svg>

11.4.4. Feuille de style attachée

<?xml-stylesheet href="stylesvg.css" type="text/css"?>
<svg width="200" height="100">
  <rect x="10" y="10" width="180" height="80"/>
  <ellipse cx="100" cy="50" rx="90" ry="40"/>
  <ellipse class="circle" cx="100" cy="50" rx="40" ry="40"/>
</svg>

11.4.5. Au niveau d'un groupe

<svg width="200" height="100">
  <g style="stroke: black; fill: none">  
    <rect x="10" y="10" width="180" height="80"/>
    <ellipse cx="100" cy="50" rx="90" ry="40"/>
    <ellipse class="circle" cx="100" cy="50" rx="40" ry="40"/>
  </g>
</svg>

11.5. Courbes de Bézier et B-splines

11.5.1. Courbes de Bézier

Les courbes de Bézier sont des courbes de degré 3. Elles sont donc déterminées par quatre points de contrôle. La courbe déterminée par les points P1, P2, P3 et P4 va de P1 à P4 et ses dérivées en P1 et P4 sont respectivement 3(P2 - P1) et 3(P3 - P4). Ceci signifie en particulier que la courbe est tangente en P1 et P4 aux droites P1P2 et P3P4.

Première courbe de Bézier Deuxième courbe de Bézier Troisième courbe de Bézier

Figure 11.2. Courbes de Bézier


Si les coordonnées des points de contrôle sont (x1, y1), (x2, y2), (x3, y3) et (x4, y4), la courbe est décrites par les formules suivantes qui donnent la courbe sous forme paramétrée.

x(t) = (1-t)3x1 + 3t(1-t)2x2 + 3t2(1-t)x3 + t3x4 pour 0 t 1
y(t) = (1-t)3y1 + 3t(1-t)2y2 + 3t2(1-t)y3 + t3y4 pour 0 t 1

La méthode de Casteljau permet la construction géométrique de points de la courbe. Soient P1, P2, P3 et P4 les points de contrôle et soient L2, H et R3 les milieux des segments P1P2, P2P3 et P3P4. Soient L3 et R2 les milieux des segments L2H et HR3 et soit L4 = R1 le milieu du segment L3R2 (cf. Figure ). Le point L4 = R1 appartient à la courbe de Bézier et il est obtenu pour t = 1/2. De plus la courbe se décompose en deux courbes de Bézier : la courbe de points de contrôle L1 = P1, L2, L3 et L4 et la courbe de points de contrôle R1, R2, R3 et R4 = P4. Cette décomposition permet de poursuivre récursivement la construction de points de la courbe.

On remarque que chaque point de la courbe est barycentre des points de contrôle affectés des poids (1-t)3, 3t(1-t)2, 3t2(1-t) et t3. Comme tous ces poids sont positifs, la courbe se situe entièrement dans l'enveloppe convexe des points de contrôle.

Si dans la construction précédente, les milieux sont remplacés par les barycentres avec les poids t et 1-t, on obtient le point de la courbe de coordonnées x(t), y(t).

Construction de Casteljau

Figure 11.3. Construction de Casteljau


11.5.2. B-splines

Les courbes B-splines sont aussi des courbes de degré 3. Elles sont donc aussi déterminées par quatre points de contrôle. Contrairement à une courbe de Bézier, une B-spline ne passe par aucun de ses points de contrôle. Par contre, les B-splines sont adaptées pour être mises bout à bout afin de former une courbe ayant de multiples points de contrôle.

Soient n+3 points P1,…,Pn+3. Ils déterminent n B-spline s1,…,sn de la manière suivante. Chaque B-spline si est déterminée par les points de contrôle Pi, Pi+1, Pi+2 et Pi+3.

Si les coordonnées des points de contrôle sont (x1, y1), …, (xn+3, yn+3), l'équation de la spline si est la suivante.

xi(t) = 1/6[ (1-t)3xi + (3t3-6t2+4)xi+1 + (-3t3+3t2+3t+1)xi+2 + t3xi+3]   pour 0 t 1
yi(t) = 1/6[ (1-t)3yi + (3t3-6t2+4)yi+1 + (-3t3+3t2+3t+1)yi+2 + t3yi+3]   pour 0 t 1

À partir des équations définissant les splines si, on vérifie facilement les formules suivantes qui montrent que la courbe obtenue en mettant bout à bout les courbes si est de classe C2, c'est-à-dire deux fois dérivable.

si(1) = si+1(0) = 1/6(Pi+1 + 4Pi+2 + Pi+3)
s'i(1) = s'i+1(0) = 1/2(Pi+3 - Pi+1)
s''i(1) = s''i+1(0) = Pi+3 - 2Pi+2 + Pi+1

11.5.3. Conversions

Puisque seules les courbes de Bézier sont présentes en SVG, il est nécessaire de savoir passer d'une B-Spline à une courbe de Bézier. La B-spline de points de contrôle P1, P2, P3 et P4 est en fait la courbe de Bézier dont les points de contrôle P'1, P'2, P'3 et P'4 sont calculés de la manière suivante. Si les coordonnées des points P1, P2, P3 et P4 sont (x1, y1), (x2, y2), (x3, y3) et (x4, y4), les coordonnées (x'1, y'1), (x'2, y'2), (x'3, y'3) et (x'4, y'4) des points P'1, P'2, P'3 et P'4 sont données par les formules suivantes pour les premières coordonnées et des formules similaires pour la seconde.

x'1 = 1/6(x1 + 4x2 + x3)
x'2 = 1/6(4x2 + 2x3)
x'3 = 1/6(2x2 + 4x3)
x'4 = 1/6(x2 + 4x3 + x4)

Les formules suivantes permettent la transformation inverse

x1 = 6x'1 - 7x'2 + 2x'3
x2 = 2x'2 - x'3
x3 = -x'2 + 2x'3
x4 = 2x'2 - 7x'3 + 6x'4