web-dev-qa-db-fra.com

Quel est le moyen le plus rapide de trouver le centre "visuel" d'un polygone de forme irrégulière?

Je dois trouver un point qui est le centre visuel d'un polygone de forme irrégulière. Par centre visuel, j'entends un point qui apparaît visuellement au centre d'une grande surface du polygone. L'application consiste à mettre une étiquette à l'intérieur du polygone.

Voici une solution qui utilise la mise en mémoire tampon interne:

https://web.archive.org/web/20150708063910/http://proceedings.esri.com/library/userconf/proc01/professional/papers/pap388/p388.htm

Si cela doit être utilisé, quel est un moyen efficace et rapide de trouver le tampon? Si un autre moyen doit être utilisé, quel est ce moyen?

Un bon exemple de polygones vraiment difficiles est un U épais et géant (écrit en Arial Black ou Impact ou dans une police de ce type).

47
Mikhil

Si vous pouvez convertir le polygone en une image binaire, vous pouvez utiliser la base qui existe dans le domaine du traitement d’image, par exemple: Un algorithme de squelette rapide Sur des images binaires représentées par blocs .

Mais ce n’est pas vraiment raisonnable dans le cas général, à cause d’erreurs de discrétisation et de travail supplémentaire.

Cependant, peut-être que vous trouvez cela utile: 

EDIT: Peut-être voudrez-vous rechercher le point qui est le centre du plus grand cercle contenu dans le polygone. Ce n'est pas nécessairement toujours dans le centre observé, mais la plupart du temps donnerait probablement le résultat escompté, et ce n'est que dans les cas légèrement pathologiques que le résultat est totalement faux.

10
Reunanen

J'ai trouvé à MapBox une très bonne solution appelée Polylabel . La source complète est disponible sur leur Github aussi.

Essentiellement, il essaie de trouver le centre visuel du polygone, comme le dit T. Austin.

 enter image description here

Certains détails suggèrent que cela pourrait être une solution pratique:

Malheureusement, calculer [la solution idéale] est à la fois complexe et lent. Les solutions publiées au problème nécessitent soit Triangulation de Delaunay contrainte ou calcul d'un squelette droit sous la forme étapes de prétraitement - toutes deux lentes et sujettes aux erreurs.

Pour notre cas d’utilisation, nous n’avons pas besoin d’une solution exacte, nous sommes prêts à le faire échanger de la précision pour obtenir plus de vitesse. Lorsque nous plaçons une étiquette sur carte, il est plus important qu’elle soit calculée en millisecondes que être mathématiquement parfait.

Une note rapide sur l'utilisation cependant. Le code source fonctionne très bien pour Javascript prêt à l'emploi, mais si vous envisagez de l'utiliser avec un polygone "normal", vous devez l'envelopper dans un tableau vide, car les fonctions ici prennent GeoJSONPolygons plutôt que des polygones normaux i.e. 

var myPolygon = [[x1, y1], [x2, y2], [x3, y3]];
var center = polylabel([myPolygon]);
11
Chris

Que diriez-vous:

Si le centre de gravité du polygone est à l'intérieur du polygone, utilisez-le, sinon:

1) Étendre une ligne du centre de la droite au polygone en divisant le polygone en deux moitiés d'égale superficie

2) Le "centre visuel" est le point situé à mi-chemin entre le point le plus proche où la ligne touche le périmètre et le point suivant coupant le périmètre dans la direction opposée au centre de gravité.

Voici quelques images pour l'illustrer:

 enter image description here

 enter image description here

7
T.Austin
7
Arron S

La méthode centroïde a déjà été suggérée plusieurs fois. Je pense que c'est une excellente ressource qui décrit le processus (et bien d'autres astuces utiles avec des polygones) de manière très intuitive:

http://paulbourke.net/geometry/polygonmesh/centroid.pdf

En outre, pour placer une étiquette d'interface utilisateur simple, il suffit peut-être de calculer le cadre de sélection du polygone (un rectangle défini par les coordonnées x et y les plus basses et les plus hautes de tout sommet du polygone) et d'obtenir son centre à:

{
    x = min_x + (max_x - min_x)/2,
    y = min_y + (max_y - min_y)/2
}

C'est un peu plus rapide que de calculer le centroïde, ce qui peut être significatif pour une application en temps réel ou intégrée.

Notez également que si vos polygones sont statiques (ils ne changent pas de forme), vous pouvez optimiser en enregistrant le résultat du calcul du centre/centre de gravité BB (relatif au premier sommet du polygone, par exemple) dans la structure de données de le polygone.

2
safdsas

Calcule la position centrale (x, y) de chaque bord du polygone. Vous pouvez le faire en trouvant la différence entre les positions des extrémités de chaque bord. Prendre la moyenne de chaque centre dans chaque dimension. Ce sera le centre du polygone.

2
ire_and_curses

Je ne dis pas que c'est le plus rapide, mais cela vous donnera un point à l'intérieur du polygone. Calculez le squelette droit . Le point que vous recherchez se trouve sur ce squelette. Vous pouvez, par exemple, choisir celui qui a la distance normale la plus courte au centre du cadre de sélection. 

1
Harald Scheirich

Que diriez-vous de trouver le "cercle" du polygone (le plus grand cercle qui correspond à l'intérieur), puis de centrer l'étiquette au centre de celui-ci? Voici quelques liens pour vous aider à démarrer:

http://www.mathopenref.com/polygonincircle.html
https://nrich.maths.org/discus/messages/145082/144373.html?1219439473

Cela ne fonctionnera pas parfaitement sur tous les polygones. un polygone ressemblant à un C aurait l'étiquette à un endroit quelque peu imprévisible. Mais l'avantage serait que l'étiquette recouvrirait toujours une partie solide du polygone.

0
Ryan Lundy