Supposons que j'ai un maillage 2D constitué de triangles non chevauchants , et un ensemble de points { p i } M i = 1 ⊂ ∪ N k = 1 T K . Quelle est la meilleure façon de déterminer dans quel triangle chacun des points se trouve?
Par exemple, dans l'image suivante, nous avons , p 2 ∈ T 4 , p 3 ∈ T 2 , donc je voudrais une fonction f qui retourne la liste f ( p 1 , p 2 , p 3 ) = [ 2 , 4 , 2 ] .
Matlab a la fonction pointlocation qui fait ce que je veux pour les maillages Delaunay, mais elle échoue pour les maillages généraux.
Ma première pensée (stupide) est que, pour tous les nœuds , parcourez tous les triangles pour savoir dans quel triangle p i se trouve. Cependant, cela est extrêmement inefficace - vous pourriez avoir à parcourir chaque triangle pour chaque point, donc cela pourrait prendre du travail O ( N ⋅ M ) .
Ma prochaine pensée est, pour tous les points , de trouver le nœud de maillage le plus proche via la recherche du plus proche voisin, puis de regarder à travers les triangles attachés au nœud le plus proche. Dans ce cas, le travail serait O ( a ⋅ M ⋅ l o g ( N ) ) , où a est le nombre maximal de triangles attachés à n'importe quel nœud du maillage. Il y a quelques problèmes résolubles mais ennuyeux avec cette approche,
- Cela nécessite la mise en œuvre d'une recherche efficace du plus proche voisin (ou la recherche d'une bibliothèque qui en dispose), ce qui pourrait être une tâche non triviale.
- Cela nécessite de stocker une liste des triangles attachés à chaque nœud, pour lequel mon code n'est actuellement pas configuré - pour le moment, il n'y a qu'une liste de coordonnées de nœud et une liste d'éléments.
Dans l'ensemble, cela semble inélégant, et je pense qu'il devrait y avoir une meilleure façon. Cela doit être un problème qui se pose souvent, donc je me demandais si quelqu'un pouvait recommander la meilleure façon d'aborder la recherche des triangles dans lesquels se trouvent les nœuds, théoriquement ou en termes de bibliothèques disponibles.
Merci!
Je ne suis pas convaincu que votre solution soit correcte. Considérez la situation où vous avez ces nœuds:
Il existe des triangles ABC et ACD. Maintenant, B est le point le plus proche de l'origine, mais l'origine est dans le triangle ACD, qui ne contient pas B.
Pour le reste, cette réponse fournit une solution qui peut dans des cas dégénérés être aussi lente queO ( N⋅ M) , mais sera généralement plus rapide - en particulier pour les triangulations de Delaunay et les triangulations proches de cela dans un certain sens.
J'envisagerais la possibilité de construire un quadtree contenant les triangles eux-mêmes. C'est-à-dire que vous avez un arbre quaternaire qui stocke dans chaque nœud (ce qui correspond à une boîte englobante):
Lorsqu'on lui donne un point P, parcourez tous les nœuds sur le chemin de la racine du quadtree à la plus petite boîte contenant P. Vous devrez examiner tous les triangles que vous rencontrez dans ces nœuds. Pour une triangulation «bien conduite», il ne devrait y avoir que quelque chose commen--√ triangles qui doivent être examinés au niveau d'un nœud qui contient n triangles dans son sous-arbre, et la profondeur doit être limitée par Journaln . Pour une triangulation «mal comportée», vous pouvez obtenir leO ( N⋅ M) travail.
la source
CGAL gère les triangulations et l'emplacement des points (et bien plus encore). En particulier, le module de triangulation 2D peut faire ce que vous voulez.
la source