web-dev-qa-db-fra.com

Existe-t-il un algorithme efficace pour générer une coque concave 2D?

Ayant un ensemble de points (2D) d'un fichier SIG (une carte de ville), je dois générer le polygone qui définit le "contour" de cette carte (sa limite). Ses paramètres d'entrée seraient les points définis et une «longueur d'arête maximale». Il produirait alors le polygone correspondant (probablement non convexe).

La meilleure solution que j’ai trouvée jusqu’à présent consistait à générer les triangles de Delaunay, puis à supprimer les bords externes plus longs que la longueur maximale. Après que toutes les arêtes externes soient plus courtes que cela, je supprime simplement les arêtes internes et récupère le polygone que je souhaite. Le problème est que cela prend beaucoup de temps et je me demande s’il existe un meilleur moyen.

59
Fabio Ceconello

Cet L'article traite de la génération efficace de simples polygones pour caractériser la forme d'un ensemble de points dans le plan et fournit l'algorithme. . Il existe également une applet Java utilisant le même algorithme ici .

2
Amirali

Un des anciens étudiants de notre laboratoire a utilisé certaines techniques applicables pour sa thèse de doctorat. Je crois que l’une d’elles s’appelle "formes alpha" et est référencée dans l’article suivant:

http://www.cis.rit.edu/people/faculty/kerekes/pdfs/AIPR_2007_Gurram.pdf

Ce document donne d'autres références que vous pouvez suivre.

10
nsanders

La réponse peut toujours être intéressante pour quelqu'un d'autre: on peut appliquer une variation de l'algorithme du carré de marche, appliquée (1) dans la coque concave, et (2) puis (par exemple, 3) différente échelles qui dépendent de la densité moyenne de points. Les échelles doivent être multiples, vous pouvez ainsi créer une grille que vous pourrez utiliser pour un échantillonnage efficace. Cela permet de trouver rapidement des échantillons vides = carrés, des échantillons qui se trouvent complètement dans un "cluster/nuage" de points et ceux situés entre les deux. Cette dernière catégorie peut alors être utilisée pour déterminer facilement la polyligne représentant une partie de la coque concave.

Tout est linéaire dans cette approche, aucune triangulation n’est nécessaire, elle n’utilise pas de formes alpha et elle est différente de l’offre commerciale/brevetée décrite ici ( http://www.concavehull.com/ )

2
monnoo

Les gars ici affirment avoir mis au point une approche du plus proche voisin pour déterminer la coque concave d'un ensemble de points se comportant "presque linéairement sur le nombre de points" . Malheureusement, leur papier semble être très bien gardé et vous devrez le leur demander .

Voici un bon bon ensemble de références qui inclut ce qui précède et pourrait vous amener à trouver une meilleure approche.

2
Vinko Vrsalovic

Le kit de développement logiciel interactif Bing Maps V8 comporte une option de coque concave dans les opérations de forme avancées.

http://www.bing.com/mapspreview/sdkrelease/mapcontrol/isdk/advancedshapeoperations?toWww=1&redig=D53FACBB1A00423195C53D841EA0D14E#JS

Dans ArcGIS 10.5.1, l'extension 3D Analyst comporte un outil Volume minimum de liaison avec les types de géométrie de coque concave, sphère, enveloppe ou coque convexe. Il peut être utilisé à n'importe quel niveau de licence.

Il existe un algorithme de coque concave ici: https://github.com/mapbox/concaveman

1
Jaybird64

Une solution simple consiste à contourner le bord du polygone. Étant donné un bord actuel de la limite reliant les points P0 et P1, le prochain point de la limite P2 sera le point avec le plus petit possible A

H01 = bearing from P0 to P1
H12 = bearing from P1 to P2
A = fmod( H12-H01+360, 360 )
|P2-P1| <= MaxEdgeLength

Ensuite, vous définissez

P0 <- P1
P1 <- P2

et répétez jusqu'à ce que vous reveniez à votre point de départ.

C'est toujours O (N ^ 2) alors vous voudrez trier un peu votre liste de points. Vous pouvez limiter le nombre de points à prendre en compte à chaque itération si vous les triez, par exemple, dans leur direction depuis le centre de la ville.

1
Mike F

Vous pouvez le faire dans QGIS avec ce plug-in: https://github.com/detlevn/QGIS-ConcaveHull-Plugin

En fonction de la manière dont vous en avez besoin pour interagir avec vos données, il est probablement utile de vérifier comment cela a été fait ici.

1
Cameron

Bonne question! Je n'ai pas du tout essayé cela, mais mon premier coup serait cette méthode itérative:

  1. Créez un ensemble N ("non contenu") et ajoutez tous les points de votre ensemble à N.
  2. Choisissez 3 points de N au hasard pour former un polygone initial P. Supprimez-les de N.
  3. Utilisez un algorithme de point dans polygone et regardez les points dans N. Pour chaque point dans N, s'il est maintenant contenu par P, supprimez-le de N. Dès que vous trouvez un point dans N qui est toujours non contenu dans P, continuez à l’étape 4. Si N devient vide, vous avez terminé.
  4. Appelez le point que vous avez trouvé A. Trouvez la ligne dans P la plus proche de A et ajoutez A au milieu de celle-ci.
  5. Retourner à l'étape 3

Je pense que cela fonctionnera tant qu'il fonctionnera assez bien - une bonne heuristique pour vos 3 points initiaux pourrait aider.

Bonne chance!

1
Rob Dickerson

PostGIS est une référence très répandue. Il commence par un embout convexe, puis le dépose, vous pouvez le voir ici.

https://github.com/postgis/postgis/blob/380583da73227ca1a52da0e0b3413b92ae69af9d/postgis/postgis.sql.in#L5819

0
Evan Carroll

Une solution rapide et approximative (également utile pour les coques convexes) consiste à rechercher les limites nord et sud de chaque petit élément est-ouest.

En fonction du niveau de détail souhaité, créez un tableau de taille supérieure/inférieure . Pour chaque point, calculez la colonne E-W dans laquelle elle se trouve, puis mettez à jour les limites supérieure/inférieure de cette colonne. Après avoir traité tous les points, vous pouvez interpoler les points haut/bas des colonnes manquantes.

Cela vaut également la peine d’effectuer une vérification rapide à l’avance pour les très fines formes minces et de décider si vous voulez classer NS ou Ew.

0
Martin Beckett