Algorithmes de base

Fran¸ois Faure c
R´sum´ e e Au plus bas niveau, les images num´riques sont repr´sent´es par des tableaux e e e de valeurs commun´ment appel´es grilles (raster graphics). Les operations de base e e consistent ` tracer des primitives g´om´triques simples et ` remplir des polygones. a e e a

Table des mati`res e
1 Grilles 2 Algorithme de Bresenham 3 Remplissage de polygones 3.1 Cas du rectangle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Cas g´n´ral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e e 3.3 Traitement des couleurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Trac´s dans OpenGL e 2 2 6 6 6 6 7

1

1

Grilles

On d´finit une image comme un tableau de valeurs, chaque valeur repr´sentant la e e couleur d’un certain point (pixel). L’aspect discret (´chantillonn´) de l’image s’att´nue si e e e on la regarde de suffisamment loin. On utilise diff´rents termes pour repr´senter de telles e e grilles, suivant le type des valeurs contenues : – bitmap les valeurs sont binaires et repr´sentent par exemple le noir et le blanc ; e – greymap les valeurs sont plus nuanc´es et repr´sentent par exemple des niveaux e e de gris ; – pixmap les valeurs comportent plusieurs composantes (canaux) afin de repr´senter e des couleurs. On cr´e une image en affectant une valeur ` chacune des cases de la grille. Ces valeurs e a peuvent provenir directement d’un appareil ` num´riser (scanner) ou ˆtre calcul´es par a e e e un programme. Une image complexe se d´compose g´n´ralement en primitives graphiques e e e (segments de droites, arcs de cercle ou d’ellipses, polygones vides ou remplis, bitmaps, ...) qui sont trac´es dans un certain ordre. Si un point fait partie de plusieurs primitives, sa e valeur finale est le r´sultat d’une combinaison des valeurs associ´es ` chacune d’elles. Ces e e a combinaisons peuvent ˆtre plus ou moins complexes (op´rateurs logiques, combinaisons e e lin´aires, valeur maxi, derni`re valeur sp´cifi´e...) et le r´sultat peut d´pendre de l’ordre e e e e e e dans lequel les primitives ont ´t´ trac´es. ee e

2

Algorithme de Bresenham

´ L’algorithme de Bresenham permet de tracer des lignes. Etant donn´ un segment de e droite allant d’un point de d´part x1 , y1 (entiers) ` un point d’arriv´e x2 , y2 (entiers) dans e a e la grille, la question est : quels pixels noircir ? En effet, un ´chantillonnage du segment e fournit en g´n´ral des valeurs non enti`res. Il faut une m´thode de choix des pixels qui e e e e garantisse la continuit´ du segment, la plus grande rectitude possible ainsi qu’un temps e de calcul faible. La figure 1 repr´sente un tel segment. e
x1 x2

y2

dy
y1

dx

Fig. 1 – Un segment de droite ´chantillonn´ e e 2

Si la pente de la droite est inf´rieure ` 1, alors nous devons allumer un et un seul pixel e a par colonne entre x1 et x2 . Notez que ce n’est pas le cas pour les lignes. Nous pourrions donc ´crire le programme suivant : e Calcul par l’´quation de droite y = mx + b e dy = y2-y1; dx = x2-x1; m = dy/dx; b = y1-m*x1; for (x=x1; x<=x2; x++) { y=m*x+b; plot(x,round(y)); } Voyons maintenant les am´liorations successives aboutissant ` un programme optimis´. e a e En particulier, on d´sire ´viter les calculs en virgule flottante pour ne traiter que des e e entiers. e Calcul de y par incr´ment dy = y2-y1; dx = x2-x1; m = dy/dx; y = y1; for (x=x1; x<=x2; x++) { plot(x,round(y)); y=y+m; } Simplification de l’arrondi dy = y2-y1; dx = x2-x1; m = dy/dx; y = y1; f = 0; for (x=x1; x<=x2; x++) { plot(x,y); f=f+m; if (f>0.5) { y = y+1; f = f-1; } } Suppression de la division par dx dy = y2-y1; dx = x2-x1; y = y1; f = 0; 3

/* <------------ */

/* <------------ */

/* <------------ */

/* <------------ */ /* <------------ */ /* <------------ */

for (x=x1; x<=x2; x++) { f=f+dy; /* <------------ */ plot(x,y); if (f>(dx/2)) { /* <------------ */ y = y+1; f = f-dx; /* <------------ */ } } Suppression de la division par 2 dy = y2-y1; dx = x2-x1; y = y1; f = 0; for (x=x1; x<=x2; x++) { plot(x,y); f=f+2*dy; /* <------------ */ if (f>dx) { /* <------------ */ y = y+1; f = f-2*dx; /* <------------ */ } } Tester le signe au lieu de comparer dy = y2-y1; dx = x2-x1; y = y1; f = -dx; /* <------------ */ for (x=x1; x<=x2; x++){ plot(x,y); f=f+2*dy; if (f>0) /* <------------ */ y = y+1; f = f-2*dx; } } Ne modifier f qu’une seule fois par passage dans la boucle dy = y2-y1; dx = x2-x1; y = y1; f = -dx; for (x=x1; x<=x2; x++) { plot(x,y); if (f>0) { y = y+1; f = f + 2*(dy-dx); /* <------------ */ 4

} else f = f + 2*dy; } Pr´calculer des valeurs e dy = y2-y1; dx = x2-x1; y = y1; f = -dx; incrE = 2*dy; incrNE = 2*(dy-dx); for (x=x1; x<=x2; x++) { plot(x,y); if (f>0) { y = y+1; f = f + incrNE; } else f = f + incrE; }

/* <------------ */ /* <------------ */

/* <------------ */

/* <------------ */

Nous arrivons enfin ` l’algorithme dit de Bresenham : a Sortir les bornes de la boucle dy = y2-y1; dx = x2-x1; y = y1; f = 2*dy-dx; incrE = 2*dy; incrNE = 2*(dy-dx); plot(x1,y1); for (x=x1+1; x<x2; x++) { if (f>0) { y = y+1; f = f + incrNE; } else f = f + incrE; plot(x,y); } plot(x2,y2); /* <------------ */ /* <------------ */

/* <------------ */

Ce programme fonctionne pour les cas o` x1 < x2 et dy ≤ dx. Il est ais´ment adaptable u e aux autres cas en changeant des signes ou en permutant les rˆles de x et y. Des algorithmes o similaires existent pour tracer des arcs d’ellipses.

5

3
3.1

Remplissage de polygones
Cas du rectangle

On d´finit un rectangle par deux points diagonaux oppos´s x1 , y1 et x2 , y2 . L’algorithme e e de remplissage consiste simplement en deux boucles imbriqu´es : e for( x=x1; x<=x2; ++x ) for( y=y1; y<=y2; ++y ) plot(x,y);

3.2

Cas g´n´ral e e

Un polygone est d´fini par une liste ordonn´e de points, chaque paire de points succese e sifs d´finissant une arˆte. On emploie un algorithme bas´ sur une ligne de balayage (scane e e line) qui parcourt un rectangle englobant le polygone ligne par ligne, comme illustr´ sur e la figure 2. On parcourt chaque ligne en partant de l’ext´rieur et en comptant le nombre e d’arˆtes intersect´es. Quand le nombre est impair on est ` l’int´rieur du polygone et on e e a e affiche la couleur d´sir´e. Quand le nombre est pair on est ` l’ext´rieur et on n’affiche rien. e e a e Les fronti`res sont d´termin´es d’une mani`re similaire ` l’algorithme de Bresenham. e e e e a
xmin xm a x

1
ymax

2 4

ym i n

5

3

Fig. 2 – Balayage ligne par ligne d’un polygone.

3.3

Traitement des couleurs

La couleur d’un polygone peut ´tre uniforme ou interpol´e (Gouraud shading). L’ine e terpolation s’effectue d’abord lin´airement sur les arˆtes entre les sommets concern´s. A e e e ` l’int´rieur, les couleurs sont interpol´es entre les arˆtes coup´es par la ligne de balayage. e e e e La figure 3 pr´sente des exemples de couleurs uniformes et interpol´es. e e

6

` ` Fig. 3 – Coloriage de polygones. A gauche, couleurs uniformes. A droite, couleurs interpol´es e

4

Trac´s dans OpenGL e

En OpenGL, on peut utiliser des points comme primitives fondamentales, en sp´cifiant e un des modes de trac´ pr´sent´s sur la figure 4. e e e Le mode de coloriage est sp´cifi´ par glShadeModel(GL FLAT) pour la couleur unie e forme et glShadeModel(GL SMOOTH) pour la couleur interpol´e (mode activ´ par e e d´faut). e

7

e e Fig. 4 – Les diff´rents modes de trac´ d’OpenGL

8