13 votes

Décomposition en polygones convexes

Cette question est un peu complexe. J'ai écrit un algorithme pour décomposer un simple polygone en sous-polygones convexes, mais maintenant j'ai du mal à prouver que c'est no optimale (c'est-à-dire le nombre minimal de polygones convexes utilisant des Points Steiner (sommets ajoutés)). Mon professeur insiste sur le fait que ce n'est pas possible avec un algorithme gourmand tel que celui-ci, mais je ne vois pas de contre-exemple.

Donc, si quelqu'un peut prouver que mon algorithme est sous-optimal (ou optimal), je l'apprécierais.

La façon la plus simple d'expliquer mon algorithme avec des images (celles-ci proviennent d'une ancienne version sous-optimale)

Ce que fait mon algorithme, c'est étendre les segments de ligne autour du point i jusqu'à ce qu'il atteigne un point sur le bord opposé.

S'il n'y a pas de sommet dans cette plage, il en crée un nouveau (le point rouge) et s'y connecte :

S'il y a es un ou plusieurs sommets dans la plage, il se connecte au plus proche. Le site généralement produit une décomposition avec le plus petit nombre de polygones convexes :

Cependant, dans certains cas, elle peut échouer - dans la figure suivante, si elle relie d'abord la ligne verte du milieu, cela créera un polygone supplémentaire inutile. Pour cela, je propose de vérifier deux fois toutes les arêtes (diagonales) que nous avons ajoutées, et de vérifier qu'elles sont toutes encore nécessaires. Si ce n'est pas le cas, supprimez-les :

Dans certains cas, cependant, cela ne suffit pas. Voir cette figure :

Remplacer a-b et c-d par a-c donnerait une meilleure solution. Dans ce scénario, cependant, il n'y a pas d'arêtes à supprimer, ce qui pose un problème. Dans ce cas, je suggère un ordre de préférence : pour décider à quel sommet connecter un sommet réflexe, il faut choisir le sommet ayant la plus haute priorité :

le plus bas) le sommet le plus proche

med) le vertex réflexe le plus proche

le plus haut) le réflexe le plus proche qui est aussi à portée de main lorsqu'on travaille à l'envers (difficile à expliquer) --

Sur ce chiffre Les deux sommets 5 et 12 sont dans l'intervalle défini par les segments de droite étendus 10-9 et 8-9, mais le sommet 5 devrait avoir la préférence parce que 9 est dans l'intervalle donné par 4-5 et 6-5, mais PAS dans l'intervalle donné par 13-12 et 11-12. c'est-à-dire que l'arête 9-12 élimine le sommet réflexe de 9, mais N'ÉLIMINE PAS le sommet réflexe de 12, l'arête 9-12 élimine le sommet réflexe à 9, mais n'élimine PAS le sommet réflexe à 12, mais elle PEUT éliminer le sommet réflexe à 5, donc 5 doit être privilégié.

Il est possible que le bord 5-12 existe toujours avec cette version modifiée, mais il peut être supprimé lors du post-traitement.

Y a-t-il des cas que j'ai manqués ?


Pseudo-code (demandé par John Feminella) -- il manque les bits sous les figures 3 et 5

assume vertices in `poly` are given in CCW order
let 'good reflex' (better term??) mean that if poly[i] is being compared with poly[j], then poly[i] is in the range given by the rays poly[j-1], poly[j] and poly[j+1], poly[j]

for each vertex poly[i]
    if poly[i] is reflex
        find the closest point of intersection given by the ray starting at poly[i-1] and extending in the direction of poly[i] (call this lower bound)
        repeat for the ray given by poly[i+1], poly[i] (call this upper bound)

        if there are no vertices along boundary of the polygon in the range given by the upper and lower bounds
            create a new vertex exactly half way between the lower and upper bound points (lower and upper will lie on the same edge)
            connect poly[i] to this new point
        else
            iterate along the vertices in the range given by the lower and upper bounds, for each vertex poly[j]
                if poly[j] is a 'good reflex'
                    if no other good reflexes have been found
                        save it (overwrite any other vertex found)
                    else
                        if it is closer then the other good reflexes vertices, save it
                else
                    if no good reflexes have been found and it is closer than the other vertices found, save it
            connect poly[i] to the best candidate
        repeat entire algorithm for both halves of the polygon that was just split
// no reflex vertices found, then `poly` is convex
save poly

Il s'avère qu'il y a un autre cas que je n'avais pas prévu : [Figure 5]

Mon algorithme tentera de connecter le sommet 1 au sommet 4, à moins que je n'ajoute une autre vérification pour m'assurer qu'il le peut. Je propose donc de placer tout ce qui est "dans la gamme" dans une file d'attente prioritaire en utilisant le schéma de priorité que j'ai mentionné plus haut, puis de prendre le sommet le plus prioritaire, de vérifier s'il peut être connecté, sinon, de le supprimer et d'utiliser le suivant. I pensez à cela rend mon algorithme O(r n log n) si je l'optimise correctement.


J'ai rassemblé un site web qui décrit vaguement mes découvertes. J'ai tendance à déplacer les choses, alors prenez-les tant que c'est chaud.

2voto

Eugene Yokota Points 43213

Que diriez-vous de quelque chose comme ça ? alt text

2voto

MarkusQ Points 15612

Je crois que l'étoile régulière à cinq branches (par exemple avec des branches alternées ayant des segments colinéaires) est le contre-exemple que vous cherchez.

Modifier en réponse aux commentaires

À la lumière de ma compréhension révisée, une réponse révisée : essayez une aiguë étoile à cinq branches (par exemple, une étoile dont les bras sont suffisamment étroits pour que seuls les trois points composant le bras opposé au point de réflexe sur lequel vous travaillez se trouvent dans la plage considérée comme de "bons points de réflexe"). Au moins, en le parcourant sur papier, il semble donner plus que l'optimal. Cependant, une dernière lecture de votre code m'amène à me demander : qu'entendez-vous par " le plus proche " (c'est-à-dire le plus proche de quoi) ?

Note

Même si ma réponse a été acceptée, ce n'est pas le contre-exemple que nous pensions initialement. Comme @Mark le fait remarquer dans les commentaires, il passe de quatre à cinq exactement au même moment que l'optimal.

Flip-flop, flip-flop

Après mûre réflexion, je pense que j'avais raison après tout. La limite optimale de quatre peut être conservée dans une étoile aiguë en s'assurant simplement qu'une paire de bras a des bords colinéaires. Mais l'algorithme en trouve cinq, même avec le rafistolage.

Je comprends :

suppression du lien mort d'ImageShack

Quand l'optimal est celui-ci :

suppression du lien mort d'ImageShack

2voto

Phil H Points 10133

Je pense que votre algorithme ne peut pas être optimal car il ne fait appel à aucune mesure d'optimalité. Vous utilisez d'autres mesures comme les sommets les plus proches et la vérification des diagonales "nécessaires".

Pour creuser un fossé entre le vôtre et un algorithme optimal, nous devons exploiter cet écart en recherchant des formes avec des sommets proches qui se décomposeraient mal. Par exemple (ignorez les lignes, je l'ai trouvé sur l'intertubenet) :

polygone concave qui forme un G ou un U http://avocado-cad.wiki.sourceforge.net/space/showimage/2007-03-19_-_convexize.png

Vous n'avez aucune protection contre le fait que le point le plus au centre soit connecté à travers le "vide" concave, qui est externe au polygone.

Votre algorithme est également assez complexe, et il se peut qu'il en fasse trop. Tout comme un code complexe, vous pouvez y trouver des bogues, car un code complexe émet des hypothèses complexes.

Envisagez une étape initiale plus étendue pour décomposer la forme en plusieurs formes plus simples - comme des triangles - puis un algorithme itératif ou génétique pour les recombiner. Vous aurez de toute façon besoin d'une étape de ce type pour combiner toutes les divisions inutiles entre vos polys convexes, et vous aurez alors peut-être limité vos décompositions possibles à des solutions sous-optimales.

À vue de nez, quelque chose comme :

  1. se décomposer en triangles
  2. générer de manière non déterministe un certain nombre de recombinaisons
  3. calculer une métrique de qualité (nombre de polys)
  4. sélectionner les meilleurs x% des recombinaisons
  5. partiellement décomposer chacune d'elles à l'aide de triangles, et générer un nouvel ensemble de recombinaisons
  6. répéter à partir de 4 jusqu'à ce qu'un certain degré de convergence soit atteint

1voto

Himadri Choudhury Points 5300

mais le sommet 5 devrait être privilégié car 9 est dans l'intervalle donné par 4-5 et 6-5

Que feriez-vous si 4-5 et 6-5 étaient encore plus convexes et que le 9 ne se trouvait pas dans leur rayon d'action ? Alors, selon vos règles, la bonne chose à faire serait de connecter 9 à 12 parce que 12 est le sommet réflexe le plus proche, ce qui serait sous-optimal.

0voto

Mark Points 49079

Je l'ai trouvé :( Ils sont en fait assez évidents.


*Imageshack mortes img*

Un trèfle à quatre feuilles ne sera pas optimal si les points de Steiner sont autorisés... les sommets rouges auraient pu être connectés.


*Imageshack mortes img*

Ce ne sera même pas optimal sans les points de Steiner... 5 pourrait être connecté à 14, supprimant le besoin de 3-14, 3-12 ET 5-12. Cela aurait pu être deux polygones mieux ! Aïe !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X