Algorithme de Bowyer-Watson
En géométrie algorithmique, l'algorithme de Bowyer-Watson est une méthode pour calculer la triangulation de Delaunay d'un ensemble fini de points dans un espace euclidien de dimension quelconque[1].
Il est parfois appelĂ© « algorithme de Bowyer » ou « algorithme de Watson », Adrian Bowyer et David Watson l'ayant indĂ©pendamment dĂ©couvert et publiĂ© dans le mĂȘme numĂ©ro du Computer Journal en 1981[1] - [2].
Description
- PremiÚre étape : insertion d'un point dans un « super-triangle » englobant.
- Insertion d'un second point.
- Insertion d'un troisiĂšme point.
- Insertion d'un quatriĂšme point.
- Insertion d'un cinquiĂšme (et dernier) point.
- Suppression des arĂȘtes du super-triangle.
L'algorithme de Bowyer-Watson est un algorithme itératif. Il procÚde en ajoutant des points, un à la fois, à une triangulation de Delaunay valide du sous-ensemble des points. AprÚs chaque insertion, tous les triangles dont le cercle circonscrit (en jaunes dans les figures ci-dessus) contient le nouveau point sont supprimés, laissant un trou polygonal « étoilé » (en rouge) qui est alors re-triangulé (en vert) en utilisant le point suivant.
Super-Triangle
Les points Ă trianguler doivent ĂȘtre compris dans un triangle englobant.
Un tel triangle peut ĂȘtre le triangle dont le cercle inscrit est le cercle minimal englobant.
Plus simplement, dans un espace Ă 2 dimensions, pour un ensemble de points , le triangle , , englobe tous ces points. En effet, par rĂ©duction d'Ă©chelle et translation tous les points peuvent ĂȘtre ramenĂ©s dans le carrĂ© , compris dans le triangle .
Trou polygonal
Les arĂȘtes du trou polygonal rĂ©sultant de la suppression des triangles sont les arĂȘtes des mĂȘmes triangles dont le triangle opposĂ© (le triangle partageant la mĂȘme arĂȘte) est soit absent (bord du super-triangle) soit parmi les triangles Ă conserver.
Un parcours des arĂȘtes dans le sens trigonomĂ©trique permet de sĂ©lectionner les arĂȘtes du trou polygonal dans le sens trigonomĂ©trique:
- Ă partir d'un triangle Ă supprimer alĂ©atoire et d'une de ses arĂȘtes.
- trouver le triangle opposé :
- si ce triangle existe et fait partie des triangles Ă supprimer: sĂ©lectionner ce triangle et la prochaine arĂȘte sur ce triangle dans le sens trigonomĂ©trique
- sinon ajouter l'arĂȘte et l'ajouter Ă la construction du polygone, puis sĂ©lectionner la prochaine arĂȘte du triangle dans le sens trigonomĂ©trique
- continuer le parcours des arĂȘtes tant que le polygone n'est pas fermĂ©
triangles = [...]
englobant = []
triangle_supprimer = [...]
triangle = triangle_supprimer[0]
arete = (triangle[0], triangle[1])
while not polygone_ferme(englobant):
t_voisin = triangles.triangle_oppose(arete)
if t_voisin in triangle_supprimer:
triangle = t_voisin
arete = t_voisin.prochaine_arete(arete)
else:
englobant.append(arete)
arete = triangle.prochaine_arete(arete)
Pseudo-code
Le pseudocode suivant à une compexité en temps de . Néanmoins il existe des optimisations pour obtenir une complexité de , par exemple en trouvant le triangle contenant le nouveau point dans son cercle circonscrit, sans avoir à vérifier tous les triangles.
def delaunay_bowyer_watson( points ):
supertri = supertriangle(points) # Un triangle contenant tous les points Ă trianguler.
# Qui devient le premier triangle de la triangulation.
triangles = [ supertri ]
fait = { supertri: False }
for sommet in points:
# Tous les triangles dont le cercle circonscrit contient le sommet à ajouter sont identifiés,
# l'ensemble de leurs arĂȘtes forment un polygone englobant.
# DĂ©marrer avec un polygone englobant vide.
englobant = []
# Pour l'instant, il n'y a aucun triangle subdivisé y supprimer.
Ă _supprimer = []
for triangle in triangles:
centre,rayon = cercle_circonscrit( triangle )
# Si ce triangle respecte la condition de Delaunay.
if x(centre) < x(sommet) and abs(x(sommet)-x(centre)) > radius:
fait[triangle] = True # Le marquer comme traité.
# Si le sommet courant est dans le cercle circonscrit du triangle courant,
if dans_cercle( sommet, centre, rayon ):
# ajouter les arĂȘtes de ce triangle au polygone candidat,
englobant += aretes( triangle )
# préparer la suppression de ce triangle.
Ă _supprimer += [ triangle ]
fait.pop( triangle )
# Effectue la suppression des triangles marqués précédemment.
for triangle in Ă _supprimer:
triangles.remove( triangle )
# Créer de nouveaux triangles, en utilisant le sommet courant et le polygone englobant.
for arĂȘte in englobant:
point_A, point_B = arĂȘte
# Ajoute un nouveau triangle Ă la triangulation.
triangle = [ point_A, point_B, sommet ]
triangles += [ triangle ]
# Il faudra le considérer au prochain ajout de point.
fait[triangle] = False
# Supprime les triangles ayant au moins une arĂȘte en commun avec le super-triangle.
triangulation = non_supertriangle( triangles )
return triangulation
Voir aussi
Cet algorithme peut ĂȘtre utilisĂ© pour obtenir un diagramme de Voronoi des points, qui est le graphe dual de la triangulation de Delaunay.
Références
- (en) David F. Watson, « Computing the n-dimensional Delaunay tessellation with application to Voronoi polytopes », Comput. J., vol. 24, no 2,â , p. 167-172 (DOI 10.1093/comjnl/24.2.167).
- (en) Adrian Bowyer, « Computing Dirichlet tessellations », Comput. J., vol. 24, no 2,â , p. 162-166 (DOI 10.1093/comjnl/24.2.162).