Triangulation de Delaunay itérative Stefanie Hahmann • Algorithme Pour simplifier l’algorithme on commencera par la triangulation du rectangle de sommets (0,0), (0,500), (500,500), (500,0), composée de deux triangles adjacents. On supposera que les points insérés se trouvent tous à l’intérieur de ce rectangle (à vérifier lors de la lecture du fichier d’entrée). On obtiendra donc une triangulation, dont l’enveloppe convexe est ce rectangle. Un algorithme incrémental est proposé en annexe A. A partir de la triangulation de départ DT4 des 4 sommets du rectangle, on insère un à un les nouveaux points (sites) dans la triangulation. L’algorithme calcule, à partir de la triangulation de Delaunay DTk des k points p0 , · · · , pk−1 déjà insérés, la triangulation de Delaunay DTk+1 obtenue après l’insertion du point pk , en changeant localement la triangulation DTk . • Tests Pour tester le programme, on utilisera des données aléatoires générées avec la routine drand48. C’est une routine standard C, qui peut être utilisée comme montré en annexe D. Essayez en plus de trouver des cas intéressants, pathologiques,... 1 ANNEXE A: Algorithme Triangulation de Delaunay en 2D - Méthode incrémentale Structure de données proposée TRIANGLE : sommet *p1, *p2, *p3; /* sommets*/ triangle *t1, *t2, *t3; /* voisins */ (éventuellement en plus: point m; /* centre du cercle circonscrit */ double r; /* rayon de ce cercle */ ) POINT : double x, y; /* coordonnées */ Les indices des points et des triangles voisins sont liés de la façon suivante: p3 t1 t2 p1 p2 t3 Les triangles ont tous la même orientation. Dans la suite on décrit un algorithme permettant d’insérer un point à une triangulation de Delaunay déjà existante. On suppose que le point à insérer se trouve dans l’enveloppe convexe des points introduits auparavant. Algorithme Input: DTl et le nouveau point pl . Output: DTl+1 Procédure: 1. Déterminer le triangle Ti , dans lequel se trouve le point pl (parcourir toute la triangulation.) 2. determiner DTL ( pl , Ti , DT L ) determiner NTL ( pl , DT L, N T L ) supprimer les triangles DT L de la triangulation DTl . 3. Rajouter pl à la liste des points de la triangulation. L’algorithme a besoin de deux listes importantes: - N T L : Liste des triangles, qui seront rajoutés à la triangulation DTl . - DT L : Liste des triangles, qui seront effacés de la triangulation DTl . On va maintenant voir en détail les deux procédures: procédure: determiner DTL Input: p point à rajouter Ti triangle, qui contient p Output: DT L liste des triangles à effacer Procédure: 1. Rajouter Ti à la liste DT L 2. FOR j=0 TO 2 DO IF Tij ∈ / DT L THEN IF p à l’intérieur du cercle circonscrit à Tij THEN /* appel récursif */ determiner DTL( p, Tij , DT L) 2 La procédure determiner DTL determine tous les triangles, dont le cercle circonscrit contient le point p. C’est un algorithme récursif, qui se termine car p est introduit dans un domaine connexe. Triangles DTL procédure: determiner NTL Input: p point à rajouter DT L liste des triangles non valables et à effacer Output: N T L liste des triangles à insérer dans la triangulation Procédure: FORALL Ti ∈ DT L DO BEGIN FOR j=0 TO 2 DO BEGIN IF Tij == ∅ THEN BEGIN Créer un nouveau triangle Tl de sommet p et d’arête kij (arête commune aux triangles Ti et Tij ). Rajouter Tl à la liste N T L END ELSE IF Tij ∈ / DT L THEN BEGIN Créer un triangle Tl de sommet p et d’arête kij établir l’adjacence entre Tl et Tij Rajouter Tl à la liste N T L END END FORALL Tk , Tl ∈ N T L (k 6= l) DO mettre à jour si il y a lieu l’adjacence entre Tl et Tk END Triangles 3 NTL ANNEXE B: Format du fichier d’entrée Le fichier d’entrée est un fichier ascii contenant la liste des coordonnées des sites: x0 y0 x1 y1 . . . . . . Attention: Toutes les coordonnées seront comprises entre 0. et 500. ANNEXE C: Format du fichier de sortie Le fichier de sortie est au format ascii, et contient des commandes en langage encapsulated-postscript, représentant la triangulation de Delaunay des sites donnés en entrée. Son format est le suivant: %!PS-Adobe-2.0 EPSF-1.2 %%BoundingBox: xmin ymin xmax ymax % xmin, ymin, xmax, ymax represente la bounding-box % englobant les donnees % debut d’une ligne segmentee x y moveto x y lineto . . . x y lineto stroke % fin d’une ligne segmentee % debut d’une ligne segmentee x y moveto x y lineto . . . x y lineto stroke % fin d’une ligne segmentee showpage Exemple d’un tel fichier: %!PS-Adobe-2.0 EPSF-1.2 %%BoundingBox: 10 10 300 450 % debut d’une ligne segmentee 10 10 moveto 300 200 lineto 200 100 lineto stroke % fin d’une ligne segmentee % debut d’une ligne segmentee 4 100 100 moveto 10 450 lineto 300 20 lineto stroke % fin d’une ligne segmentee showpage Ce fichier peut être visualisé grâce à la commande ghostview < nom de fichier > ANNEXE D: Données d’entrée aléatoires Pour générer des fichiers d’entrée aléatoires, on utilisera les fonctions suivantes dans le programme: #include <time.h> #include <math.h> . . . /* Initialisation de la serie aleatoire */ srand48((long) time(0)); printf("%lf %lf . . . ANNEXE E: ", drand48( ), drand48( )); Littérature: voir cours 5