Chapitre 3 Remplissage des polygones Achraf Othman Support du cours : www.achrafothman.net Polygones dans le plan Définition Un polygone Π dans le plan est une suite de segments Π = (S1, S2, … , Sn) avec n ∈ℵ* Et pour i = 1,…,n, le segment Si est de la forme Si = [Si-1, Si] Où Pi est un point du plan pour i=0,…,n avec P0= Pn Pi s’appelle un sommet du polygone Les segments Si s’appellent les arêtes du polygone. 2 www.achrafothman.net Polygones dans le plan Points intérieurs et points extérieurs Soit un polygone Π = (S1, S2, … , Sn) et un point M du plan qui ne se trouve pas sur aucun des segments du Π. Considérons une demi-droite ∆ issue de M qui ne contient aucun des sommets du polygone Π.. On dit que le point M est à l’intérieur au polygone Π si la demi-droite ∆ intersecte un nombre impair de segments de Π. Sinon, si le nombre est pair, on dit que le point M est à l’intérieur du polygone Π. 3 www.achrafothman.net Polygones dans le plan Points intérieurs et points extérieurs 4 www.achrafothman.net Polygones dans le plan Polygones convexes Un polygone Π = (S1, S2, … , Sn) est dit convexe si pour tous points M et M’ qui sont intérieurs au polygone Π, le segment [MM’] est entièrement composé de points intérieurs au polygone Π. 5 www.achrafothman.net Principe du remplissage de polygones Considérons un polygone Π du plan, dont tous les sommets ont des coordonnées entières. Le problème du remplissage consiste à trouver un algorithme permettant de parcourir tous les points de coordonnées entières du plan qui sont intérieurs du polygone. Parcourir et afficher tous les pixels qui se trouvent à l’intérieur d’un polygone donné sur un écran ou une image numérique. 6 www.achrafothman.net Principe du remplissage de polygones Le principe du remplissage consiste à calculer des segments horizontaux inclus du polygone. 7 www.achrafothman.net Principe du remplissage de polygones Nous devons déterminer, pour chaque horizontale, quels pixels sont à l’intérieur du polygone: Les marquer Les afficher en couleur En faisant cela itérativement pour toutes les horizontales. On remplit complètement le polygone. 8 www.achrafothman.net Principe du remplissage de polygones Le remplissage, pour chaque ligne horizontale, sera décomposé en trois étapes: 1) 2) 3) Trouver les extrémités des segments horizontaux inclus dans le polygone Π. Ces extrémités correspondent à des intersections de la ligne horizontale avec les arêtes du polygone. Trier les extrémités obtenues à l’étape 1 dans l’ordre des coordonnées X croissantes. Afficher tous les pixels qui sont à l’intérieur du polygone entre paires d’extrémités. On utilise la règle de parité pour déterminer qu’un pixel se trouve à l’intérieur de Π. 9 www.achrafothman.net Parcours des arêtes Comment trouver les extrémités sur chaque horizontale Les extrémités des segments horizontaux inclus dans le polygone correspondent à des intersections d’une horizontale avec les arêtes du polygone, donc à des points sur les arêtes. 10 www.achrafothman.net Algorithme de parcours des arêtes du polygone (1) Détermination des extrémités des segments horizontaux inclut dans le polygone par un parcours des arêtes du polygone. Chaque arête du polygone va d’un pixel (xbas, ybas) à un pixel (xhaut, yhaut) avec ybas < yhaut. On fait varier l’ordonnée y de ybas à yhaut, et on obtient la relation suivante pour les coordonnées de l’intersection de notre arête avec les horizontales: Où 11 est l’inverse de la pente de la droite. www.achrafothman.net Algorithme de parcours des arêtes du polygone (2) Pour se ramener à l’arithmétique entière, on décompose la donnée 1/m en : Son numérateur numerat = xhaut – xbas, qui est de signe quelconque. Son dénominateur denomin = yhaut – ybas, qui est toujours strictement positif. On considère une variable entière increment telle que : représente, à une constante inférieure à 1 près, la partie fractionnaire de xi. La variable increment doit être augmentée de la quantité numerat à chaque étape (itération). On dessine un pixel dont l’abscisse est arrondi de la valeur xi. 12 www.achrafothman.net Algorithme de parcours des arêtes du polygone (3) Cette valeur arrondie doit être augmentée lorsque la quantité dépasse 1. On note Q la partie entière de , alors l’abscisse du pixel à afficher doit être augmentée de la valeur Q. Il faut alors ramener la quantité à sa partie fractionnaire pour qu’elle redevienne inférieure à 1. Astuce 1 : la variable increment doit rester ramenée entre 0 et (denomin-1) Astuce 2 : la variable increment doit être diminué de la Q x denomin. 13 www.achrafothman.net Algorithme de parcours des arêtes du polygone (4) : initialisation L’initialisation correcte de la variable increment dépend de la pente de la droite et du caractère gauche ou droite de l’arête du polygone : Pour une arête gauche avec numerat>0 (pente positive), on a : int increment = denominateur – 1 ; Pour une arête droite avec numerat > 0 (pente positive), on a : int increment = -1 ; Pour une arête gauche avec numerat <= 0 (pente négative), on a : int increment = 0 ; Pour une arête droite avec numerat <= 0 (pente négative), on a : int increment = - denominateur ; 14 www.achrafothman.net Algorithme de parcours des arêtes du polygone (5) void gauche_pente_pos (int xbas, int ybas, int xhaut, int yhaut, int couleur) { int y; int x = xbas; int numerateur = xhaut – xbas; int denominateur = yhaut / ybas; int increment = denominateur – 1; int Q; for(y = ybas ; y <= yhaut ; y++) { PutPixel(x,y,couleur); increment += numerateur; Q = increment / denomintaeur; x += Q; increment -= Q * denominateur; }} 15 www.achrafothman.net 16 www.achrafothman.net Algorithme de parcours des arêtes du polygone (7) Prenons l’exemple d’une arête : denomin = yhaut – ybas = 10 numerat = xhaut – xbas = 4 On suppose, par exemple que : xbas = 3 et ybas = 0 pente positive, initialisation : increment = denomin – 1 = 9 Algorithme : 17 www.achrafothman.net void gauche_pente_pos (int xbas, int ybas, int xhaut, int yhaut, int couleur) { int y; int x = xbas; int numerateur = xhaut – xbas; int denominateur = yhaut / ybas; int increment = denominateur – 1; int Q; for(y = ybas ; y <= yhaut ; y++) { PutPixel(x,y,couleur); increment += numerateur; Q = increment / denomintaeur; denomin = yhaut – ybas = 10 numerat = xhaut – xbas = 4 x += Q; increment -= Q * denominateur; }} y 0 1 2 3 4 5 6 7 8 9 10 increment 9 9+4=13 7 7+4=11 1+4=5 5+4=9 9+4=13 3+4=7 7+4=11 1+4=5 5+4=9 x 3 3+1=4 4 4+1=5 5+0=5 5+0=5 5+1=6 6+0=6 6+1=7 7+0=7 7+0=7 (3,0) (4,1) (4,2) (5,3) (5,4) (7,8) (7,9) (7,10) Pixel 18 www.achrafothman.net (5,5) (6,6) (6,7) Remplissage de polygones Le cas du polygone convexe 19 www.achrafothman.net Remplissage de polygones Algorithme 1 : Le cas du polygone convexe Avantage : pour chaque horizontale, on a au plus un segment horizontal inclus dans le polygone Π. Idée de l’algorithme : Partir du bas du polygone vers le haut. Parcourir les arêtes qui bordent le polygone à gauche et à droite (en utilisant l’algorithme précédent). 20 www.achrafothman.net Remplissage de polygones Algorithme 1 : Le cas du polygone convexe Par exemple, pour le polygone Π : Parcourir les arêtes [AH] et [BC] Lorsqu’on arrive à la hauteur 2 On remplace l’arête [BC] par [CD] Parcourir les arêtes [AH] et [CD] Lorsqu’on arrive à la hauteur 3 On remplace l’arête [AH] par [HG] Parcourir les arêtes [HG] et [CD] … … … Jusqu’à la hauteur 7. 21 www.achrafothman.net Remplissage de polygones Algorithme 2 : La tables des arêtes actives TAACONV On fait varier une variable y de l’ordonnée du point le plus bas du polygone Π à l’ordonnée du point le plus haut. On maintient une table des arêtes actives TAACONV qui: Pour une valeur donnée de y, code les deux arêtes du polygone qui intersectent : L’horizontale de hauteur y Les abscisses arrondies des intersections de ces arêtes avec l’horizontale de hauteur y Exemple : 22 www.achrafothman.net Remplissage de polygones Algorithme 2 : La tables des arêtes actives TAACONV On représente la table des arêtes actives pour Π et pour y = {4,5,6} Exemple pour y = 4 : 23 www.achrafothman.net TAACONV y= 4: 24 yhaut x numerat denomin yhaut x numerat denomin 6 4 -1 3 5 9 1 3 www.achrafothman.net Remplissage de polygones Algorithme 2 : La tables des arêtes actives TAACONV Lorsque la variable y est incrémentée, il faut mettre à jour la table des arêtes actives TAACONV, en remplaçant les arêtes pour laquelles y=yhaut par les arêtes pour lesquelles y=ybas. Mettre à jour la donnée x des autres arêtes suivant l’algorithme de parcours des arêtes. En déterminant la variable increment. En mémorise cette donnée dans increment[0] pour l’arête à gauche et increment[1] pour l’arête à droite. 25 www.achrafothman.net TAACONV y= 5: 26 yhaut x numerat denomin yhaut x numerat denomin 6 4 -1 3 7 9 -4 2 www.achrafothman.net TAACONV y= 6: yhaut x numerat denomin yhaut x numerat denomin 7 3 2 1 7 7 -4 2 Remplissage de polygones La table des arêtes globale TACONV Pour introduire rapidement une nouvelle arête telle que y=ybas, on construit une table des arêtes globale (TACONV) contenant toutes les arêtes non-horizontales du polygone, classées suivant leurs ybas. Exemple : 28 www.achrafothman.net Remplissage de polygones La table des arêtes globale TACONV 7 3 2 1 7 10 -4 2 4 6 4 -1 3 3 5 9 1 3 2 3 6 -2 2 2 7 2 1 yhaut xbas numerat denomin yhaut xbas numerat denomin Coordonnées de Y 7 6 5 TACONV 29 www.achrafothman.net Remplissage de polygones La table des arêtes globale TACONV Chaque deux arêtes doivent apparaître dans la table TACONV ordonnées de gauche à droite. Une arête a1 est à gauche d’une arête a2 si et seulement si : Soit a1.xmin < a2.xmin Soit a1.xmin = a2.xmin et (comparaison des pentes) Ce qui exprime en nombre entiers : a1.numerat x a2.numerat < a2.numerat x a1.denomin 30 www.achrafothman.net . Remplissage de polygones Algorithme E0 (init) : construite TACONV E1 : initialiser y à la plus petite valeur min(ybas) de ybas. E2 : copier les deux arêtes de la table TACONV à la hauteur 0 (la plus basse, correspondant à y) dans la table TAACONV. Initialiser les deux variables increment. E3 : Répéter tant que y est strictement inférieur à la plus grande valeur possible de yhaut : E3.1 : Afficher les pixels entre les deux pixels (x,y) correspondant aux deux éléments de TAACONV. E3.2 : Remplacer les arêtes de TAACONV qui ont leur yhaut égal à y par les arêtes de la table TACONV pour lesquelles ybas=y. E3.3 : Mettre à jour les valeurs de x dans TAACONV pour incrémenter y. E3.4 : incrémenter y. 31 www.achrafothman.net Exercice d’application Soient A(1,5) et B(7,1) deux points. En considérant le segment [AB] comme une arête gauche de polygone, appliquer l’algorithme de parcours des arêtes utilisé dans l’algorithme de remplissage de polygones pour parcourir l’arête [AB]. En considérant le segment [AB] comme une arête droite de polygone, appliquer l’algorithme de parcours des arêtes utilisé dans l’algorithme de remplissage de polygones pour parcourir l’arête [AB]. Refaire le même exercice pour A(1,2) et B(6,4). 32 www.achrafothman.net Exercice d’application Appliquer l’algorithme de remplissage de polygones au polygone convexe représenté ci-dessus. 33 www.achrafothman.net Fenêtrage de polygones 2D 34 www.achrafothman.net 35 www.achrafothman.net 36 www.achrafothman.net Le support du cours est disponible sur le site : www.achrafothman.net 37 www.achrafothman.net Références 38 www.achrafothman.net