Univ. Lille1 - Licence Informatique 2ème année 2012-2013
Algorithmes et Programmation Impérative 2
TP : Coloriage
Objectifs : Colorier une région du plan délimitée par un bord fermé.
1 Rappel sur le module Graphics
1.1 Description rapide du module
Le module Graphics ore quelques primitives graphiques permettant d'eectuer des tracés simples. En voici quelques unes.
1. open_graph:string → unitouvre une fenêtre graphique dont les dimensions sont données dans la chaîne passée en paramètre sous la forme " lxh"oùl et hsont à remplacer par la largeur et la hauteur (en nombre de pixels) de la fenêtre désirée. Attention à bien laisser un espace avant la largeur !
2. close_graph:unit → unitferme la fenêtre graphique.
3. rgb : int → int → int → color donne une couleur dénie par ses trois composantes rouge, verte et bleue désignée par chacune par un entier compris entre 0 et 255.
4. black,white,red,green,blue,yellow,cyan, magenta:color couleurs prédénies.
5. set_color:color → unitdénit la couleur courante pour les prochains tracés.
6. point_color:int → int → color renvoie la couleur du point.
7. plot : int → int → unit dessine un point dont les coordonnées sont passées en para- mètres.
8. moveto:int → int → unitpositionne la position courante au point donné en paramètre.
9. lineto:int → int → unit trace un segment depuis la position courante jusqu'au point donné en paramètre. La position courante devient ce point.
10. draw_rect:int → int → int → int → unittrace un rectangle dont le coin inférieur gauche est donné par les deux premiers paramètres, le troisième étant la largeur, et le qua- trième la hauteur.
11. draw_circle:int → int → int → unittrace un cercle dont le centre est donné par les deux premiers paramètres, le troisième étant le rayon.
Pour plus de renseignements sur le moduleGraphics, consultez la documentation ocielle.
1.2 Utiliser le module graphique depuis l'interpréteur
> ocaml graphics.cma
1.3 Compiler un programme utilisant le module graphique
> ocamlc -o <nom executable> graphics.cma <nom programme source>
2 Coloriage
On veut écrire une procédure de coloriage de régions du plan délimitée par des courbes fermées.
Le coloriage s'arrête une fois le bord de la région atteinte.
Par exemple, la gure 1 montre une gure représentant deux rectangles, l'un étant inclus dans l'autre. Dans la gure 2 la région du plan délimitée par les bords des deux rectangles a été coloriée en rouge. Et enn dans la gure 3 la région intérieur au petit rectangle a été coloriée en bleu.
Figure 1 Une gure non coloriée
On supposera dans ce travail que les bords des régions sont de couleur noire, et qu'on ne colorie pas en noir.
let couleur_bord = Graphics.black
2.1 Coloriage de régions convexes
Une région est convexe si à chaque fois qu'on prend deux points intérieurs ou sur le bord de cette région, le segment qui les relie est entièrement inclus dans la région. Les rectangles, les cercles, ellipses sont des régions convexes (cf gure 4. Les étoiles ne sont pas des régions convexes (cf 5).
Figure 2 Une région coloriée
Vous allez dans les questions qui suivent colorier des régions convexes. Aucune méthode n'est imposée.
Question 1 Dessinez un rectangle (à bords noirs) dans une fenêtre graphique, et coloriez son intérieur en rouge en connaissant les coordonnées de ce rectangle.
Question 2 Dessinez un rectangle, et coloriez son intérieur en connaissant uniquement les coordonnées d'un point de l'intérieur.
Question 3 Votre méthode de coloriage convient-elle pour des cercles ? des ellipses ? des losanges ? Testez !
Question 4 Et pour une région non convexe ?
2.2 Coloriage de régions quelconques
Si votre méthode de coloriage convient pour toute région qu'elle soit convexe ou non, c'est très bien ! Néanmoins, vous allez découvrir dans cette partie un algorithme récursif qui convient pour toute région.
Cet algorithme récursif se résume à :
on colorie le pixel courant de la couleur voulue et on appelle récursivement l'algorithme sur chacun de ses voisins qui n'est pas sur le bord
Reste à préciser quels sont les voisins d'un pixel. Un pixel de coordonnées(x, y)a quatre voisins : 1. le voisin du nord de coordonnées(x, y+ 1);
2. le voisin de l'est de coordonnées(x+ 1, y);
Figure 3 Deux régions coloriées
3. le voisin du sud de coordonnées(x, y−1); 4. et le voisin de l'ouest de coordonnées(x−1, y).
Question 5 Programmez la fonctionvoisinsde type
int → int → (int∗int)array,
qui renvoie la liste des voisins du pixel passé en paramètre par ses coordonnées, sous forme d'un tableau de coordonnées.
Question 6 Programmez une procédure de coloriage qui prend les coordonnées d'un point intérieur à la région à colorier ainsi qu'une couleur, et colorie cette région. CU : la couleur passée en paramètre ne doit pas être la même que celle utilisée pour tracer le bord de la région à colorier.
Question 7 Testez votre procédure pour diérentes régions convexes ou non.
Par exemple, après avoir dessiné les contours dénis par le le code suivant let _ =
draw_poly [| (0,0); (20,0); (25,40); (35,40);
(40,0); (60,0); (40,100); (20,100); (0,0) |] ; draw_poly [| (25,50); (35,50); (30,80); (25,50) |] ; draw_poly [| (100,0); (120,0); (120,50); (130,50);
(150,60); (150,90); (130,100); (120,100);
(100,100); (100,0) |] ; draw_rect 200 0 20 100 ;
draw_arc 210 100 20 20 300 360 ; draw_arc 210 100 20 20 0 240
Figure 4 Régions convexes
coloriez en rouge la région contenant le point (210,101), en jaune celle contenant le point(10,10), en vert celle contenant le point(210,91)et enn en magenta celle contenant le point(110,91).
Question 8 On peut envisager une autre notion de voisins en incluant les voisins 1. du nord-est, de coordonnées(x+ 1, y+ 1);
2. du sud-est, de coordonnées(x+ 1, y−1); 3. du sud-ouest, de coordonnées(x−1, y−1); 4. et du nord-ouest, de coordonnées(x+ 1, y−1).
Modiez votre fonctionsvoisinspour inclure ces nouveaux pixels voisins, puis testez votre procédure de coloriage.
Que constatez-vous ? Expliquez !
Figure 5 Régions non convexes