Comme vous le voyez sur la figure, la question est la suivante:
Comment trouver le rectangle minimum de surface (MAR) ajusté sur les points donnés?
et une question complémentaire est:
Existe-t-il une solution analytique au problème?
(Un développement de la question consistera à adapter une boîte (3D) à un groupe de points dans un nuage de points 3D.)
Dans un premier temps, je propose de trouver la coque convexe pour les points qui reforment le problème (en supprimant ces points ne sont pas impliqués dans la solution): lier un MAR à un polygone. La méthode requise fournira X ( centre du rectangle ), D ( deux dimensions ) et A ( angle ).
Ma proposition de solution:
- Trouver le centroïde du polygone (voir Recherche du centre de la géométrie de l'objet? )
- [S] Ajuster un rectangle ajusté simple, c'est-à-dire parallèle aux axes X et Y
- vous pouvez utiliser la
minmax
fonction pour X et Y des points donnés (par exemple, les sommets d'un polygone)
- vous pouvez utiliser la
- Stocker la surface du rectangle ajusté
- Faire pivoter le polygone autour du centre de gravité, par exemple, d'un degré
- Répéter de [S] jusqu'à une rotation complète
- Signaler l'angle de l'aire minimale comme résultat
Cela me semble prometteur, mais les problèmes suivants existent:
- choisir une bonne résolution pour le changement d’angle pourrait être difficile,
- le coût de calcul est élevé,
- la solution n'est pas analytique mais expérimentale.
Pour compléter l'excellente solution de @ julien, voici une implémentation fonctionnelle dans
R
, qui pourrait servir de pseudocode pour guider toute implémentation spécifique au SIG (ou être appliquée directement dansR
, bien sûr). L'entrée est un tableau de coordonnées de points. La sortie (la valeur dembr
) est un tableau des sommets du rectangle de délimitation minimal (le premier étant répété pour le fermer). Notez l'absence complète de tout calcul trigonométrique.Voici un exemple d'utilisation:
Le timing est limité par la vitesse de l'algorithme de coque convexe, car le nombre de sommets dans la coque est presque toujours beaucoup plus petit que le total. La plupart des algorithmes de coque convexe sont asymptotiquement O (n * log (n)) pour n points: vous pouvez calculer presque aussi vite que vous pouvez lire les coordonnées.
la source
Je viens juste de le mettre en œuvre moi-même et de poster ma réponse sur StackOverflow , mais je me suis dit que je laisserais tomber ma version ici pour que les autres le voient:
Voici quatre exemples différents de celui-ci en action. Pour chaque exemple, j'ai généré 4 points aléatoires et trouvé la boîte englobante.
C'est relativement rapide aussi pour ces échantillons sur 4 points:
la source
points = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
, et le résultatarray([[1.00000000e+00, 6.12323400e-17], [0.00000000e+00, 0.00000000e+00], [6.12323400e-17, 1.00000000e+00], [1.00000000e+00, 1.00000000e+00]])
obtenu correspond à l'unité carrée (y compris certaines erreurs d'arrondi en virgule flottante). Note: un carré est juste un rectangle avec des côtés égaux, donc je suppose que s'il peut gérer un carré, il se généralise à tous les rectangles.Il existe un outil dans Whitebox GAT ( http://www.uoguelph.ca/~hydrogeo/Whitebox/ ) appelé Minimum Bounding Box pour résoudre ce problème précis. Il y a aussi un outil de coque convexe minimum là aussi. Plusieurs outils de la boîte à outils Patch Shape, par exemple l'orientation et l'allongement du patch, sont basés sur la recherche du cadre de sélection minimal.
la source
Je suis tombé sur ce fil en cherchant une solution Python pour un rectangle de délimitation à aire minimale.
Voici ma mise en œuvre , pour laquelle les résultats ont été vérifiés avec Matlab.
Le code de test est inclus pour les polygones simples, et je l’utilise pour trouver le cadre de délimitation minimal 2D et les directions des axes pour un PointCloud 3D.
la source
Merci @ Whuber réponse. C'est une excellente solution, mais lente pour les gros nuages de points. J'ai trouvé que la
convhulln
fonction dans le package Rgeometry
est beaucoup plus rapide (138 s contre 0,03 s pour 200000 points). J'ai collé mes codes ici pour quiconque est intéressant pour une solution plus rapide.Deux méthodes obtiennent la même réponse (exemple pour 2000 points):
la source
Je recommande simplement la fonction intégrée de OpenCV
minAreaRect
, qui trouve un rectangle pivoté de la surface minimale entourant le jeu de points 2D en entrée. Pour voir comment utiliser cette fonction, on peut se référer à ce tutoriel .la source