Je suis coincé avec ce petit problème et mon algorithme pour résoudre cela ne tient pas pour tous les cas. Est-ce que quelqu'un a une idée de savoir comment résoudre ce problème?
Voici un exemple de polygone: strong> p> exemple d'exemple http://img148.imageshack.us/img148/8804/poly.png p> Nous avons une liste de points dans la commande CW définissant le polygone. Nous pouvons également interroger si un point est un point de coupe avec entrée: Sortie: Cet algorithme ne tienne pas si vous commenciez AT is_cut (p) code>, où
p code> est un point donné. Maintenant, nous voulons calculer de nouveaux polygones causés par cette "coupe". P>
{A, C1 , B, C4, C, C5, D, C6, E, C3, C2} Code> P>
{A, C1, C2} code>, < code> {b, c4, c3, f, c2, c1} code>,
{d, c6, c5} code>,
{e, c3, c4, c, c5, c6 } code> p>
C code> ou
f code>. p> p>
4 Réponses :
Tout d'abord vous devez calculer quels segments de la ligne de coupe appartiennent à votre polygone interne de d'origine. C'est un problème classique, et sa solution est simple. Étant donné que vos points Maintenant, nous pouvons construire algorithme récursif simple pour les polygones de coupe. Compte tenu de votre grand tableau d'entrée, {a, c1, b, c4, c, c5, d, c6, e, c3, f, c2}, commencez à tout point de polygone, par exemple, Pour deux derniers cas, ajouter ces noeuds dans l'ordre que vous rencontrez à Si vous devez aller au-delà du dernier élément, circuit au premier élément du tableau d'entrée. p>
Tôt ou tard, vous rencontrerez le nœud initial que vous traversions à partir. Maintenant, dans le C'est la solution que je vois. Mais il est geomentry de calcul, donc il peut tourner un peu plus complexe qu'il n'y paraît. P>
Pour notre exemple, commencer à partir de Voila - vous obtenez 4 polygones que vous avez besoin p>.
(*) Notez qu'il exige une plus grande représentation « mathématique » de la ligne. Par exemple, si l'un des sommets du polygone est sur la ligne, il faut doubler le sommet, à savoir si Parfois (pas dans cet exemple), il peut conduire à la coupe des polygones "vides", comme c1, c2, c3 ... c6 code> sont disposés le long de la ligne dans cet ordre exactement, puis segments
C1-C2 code>,
-c4 c3 code> etc appartiendront toujours de polygones internes (*). p>
b code>; ajouter à un tableau
Résultat code> em>. Traverse le tableau d'entrée vers l'avant. Si vous rencontrez p>
Résultat code> em>. Li>
ck code> noeud, où
k code> est impair strong>, rechercher les
c (k + 1) code> et maintenir déplacement de sa position. li>
ck code> noeud, où
k code> est encore strong>, rechercher les
c (k-1) code>, sauter à sa position et garder traversant néanmoins en avant. li>
ul>
Résultat code> em> array. Ajouter
ck code> noeud jeu
cut code> em>, et ajouter un autre noeud (
c (k + 1) code> ou
c (k-1) code>, selon ce que vous avez) dans un ensemble global
fait code> em>. p>
Résultat code> em> array vous avez un polygone que vous avez coupé. Souviens toi. Répétez la procédure récursive, à partir de la position de chaque noeud qui appartient à
cut code> em> ensemble et ne pas appartenir à l'économie mondiale
fait code> < / em> ensemble. p>
b code>: p>
DONE = {} code> em>, commencer à partir de
b code>. Après la première passe, vous obtenez
Résultat = [b, c4, c3, f, c2, c1] code> em>,
cut = {c4, c2 } code> em>,
= {fait c3, c1} code> em>; Recurse
c4 code> et
c2 code> noeuds. Li>
done = {c3;} c1 code> em>, commencer à partir de
c4 code> (récursion de 1). Après ce passage, vous obtenez
Résultat = [c4, c, c5, c6, e, c3, c4] code> em>,
cut = {c5 , c3} code> em>,
fait + = {c6, c4} code> em>; Recurse
c5 code>. Li>
done = {c3, c4 c1;}; c6 code> em>, commencer à partir de
c2 code> (récursion de 1). Après ce passage, vous obtenez
Résultat = [c2, a, c1] code> em>,
cut = {c1} code> em >,
fait + = {} c2 code> em>; Ne pas récursif à
c1 code>, car il est dans
fait code> em> ensemble; li>
done = {c3, c4 c1;; c6; c2} code> em>, commencer à partir de
c5 code> (récursion de 2). Après ce passage, vous obtenez
Résultat = [c5, d, c6] code> em>,
cut = {c5} code> em >,
fait + = {} c6 code> em>; Ne pas récursif
c5 code>, car il est dans
fait code> em> ensemble; li>
Ol>
c code> point a été un peu plus près du côté droit et sur la ligne rouge, la ligne aurait < code> [c1, c2, c3, c, c, c6] code> points sur elle, et l'ensemble de polygone serait
[a, c1, b, c, c, c, d, c6, e , c3, f, c2] code>. p>
[a, a, a] code>. Si vous ne les avez pas besoin, vous pouvez les éliminer à un stade avancé. Quoi qu'il en soit, il est la géométrie de calcul avec un nombre immense de cas à la frontière. Je ne peux pas les inclure tous dans une réponse ... p>
Citation: ... Segments C1-C2, C3-C4 etc. appartiendra toujours à des internes du polygone ... I>, ne tiendra pas toujours. Par exemple, supprimez les points de coupe c4 code> et
c5 code> et que
c code> soit le point de coupe.
@Bart K., il n'y a aucune erreur dedans. Explication ajoutée.
Désolé, je ne voulais pas impliquer que tu avais tort. C'est juste que vous faites que cela sonne vraiment facile, alors qu'il y ait (comme vous le mentionnez vous-même) un peu de cas de coin difficiles, il faut rendre compte.
Superbe réponse! Génial que vous avez piétiné après que vous ayez expliqué quoi faire.
Vous pouvez appliquer Weiler ATHERTON Coupure (efficacement de ce que Pavel suggère), mais Il y a une énorme mise en garde. P>
En raison d'erreurs de points flottants, l'algorithme d'écrêtage W / A est extrêmement difficile à faire fonctionner bien - dans des cas tels que la ligne de clipping traversant un sommet ou précisément le long d'un bord du polygone, l'algorithme peut devenir confus Quel "chemin" autour du périmiter du polygone il devrait suivre et il génère ensuite des résultats incorrects. P>
Ce que je suggère peut être facilement étendu à la manipulation de tels cas, mais mon algorithme n'a rien à savoir sur l'arithmétique de point flottant, il traverse simplement les matrices données (qui ne nécessitent pas beaucoup de précision).
Ce qui est correct: "C'est une géométrie informatique avec un immense nombre de cas frontaliers" ou "[IT] peut être facilement étendu à la manipulation de tels cas"? Toute personne qui a tenté de mettre en œuvre ces méthodes peut vous dire que l'algorithme ci-dessus ne prend que quelques minutes à mettre en œuvre et beaucoup plus longtemps de travailler dans un sens généralisé et utile. Si vous apportez une seule décision erronée (facilement effectuée lorsque tout le monde sait que les "ordinateurs ne peuvent pas faire de maths") lors de la traversée de la hiérarchie de votre nœud, vous générerez des sorties incorrectes.
Choisissez un pont qui n'est pas sur la coupe (A par exemple) et définissez-le sur le côté gauche (il ne doit pas jouer à Actaly) P > Lorsque vous passez des points sur la coupe, le côté du point que vous atteignez le changement. Donc, vous trouvez des points de gauche / droit. P> problème est que vous devriez également considérer que l'ordre des points devrait être de manière prérogée. (dans le sens des aiguilles d'une montre, par exemple) p> pour chaque polygone que vous avez touché la mi-script dans une seule direction Une fois. p> Si vous "débordez" c cela signifie que vous atteignez le polynome extérieur.
Vous pourriez résoudre ce problème si vous définissez C0 et Cmax qui réside sur Polgon et que vous avez P> input = {a, c1, c0 ,c1, b, c4, c, c5, d, c6, c7, c6, e, c3, f, c2}
Le plus simple à mettre en œuvre est Sutherland-Hodgman . Le problème avec c'est qu'il laisse de petits rubans de zone zéro reliant les polys d'un côté de la ligne. Dans votre exemple, cela vous donnerait quelque chose comme: p>
{A C2 C3 E C6 C5 C C4 C1} et {B C1 C2 F C3 C6 D C5 C4} P> blockQuote>
Si vous pouviez vivre avec ceci ou déterminer comment les casser dans les morceaux que vous souhaitez, vous constateriez que le code qui faisait l'écrêtage réel serait aussi simple que possible. P>
La mise en œuvre nécessite simplement deux piles et une seule passe à travers les sommets de votre polygone. Sur chaque sommet, vous vérifiez si vous avez traversé la ligne depuis le sommet précédent. Si tel est le cas, calculez le point de croisement et poussez-le sur l'une des piles. Puis appuyez sur le nouveau sommet sur l'une des piles. Vraiment facile. P>
Quand j'ai vu votre photo, j'ai enfin compris la sortie. Cependant, je ne pense pas, étant donné cette entrée, l'ordinateur peut en quelque sorte supposer de manière magique que les coordonnées C appartiennent tous ensemble. Je pense donc que cela formerait les coordonnées du polygone, vous avez également besoin d'une matrice d'entrée séparée spécifiant laquelle de ces indices sont les indices à couper. Plus logique serait: un polygone et 1 vecteur qui définit la ligne de coupe
Correct, j'ai calculé les points C_n avant, donc je peux fournir une fonction is_cut (p), qui formerait une telle liste {C1, ..., cn}, où n mod 2 == 0. Je suis désolé pour le Image, mais Stackoverflow ne me permet pas encore de poster des images :(.
J'ai aussi ajouté un algorithme pseudocode que j'ai utilisé pour le savoir.
hm ... cette image me rappelle quelque chose que je vois tous les jours dans le métro. (Pic) alloyfirms.ru/bank/5295_moscou.gif
@PAVEL: Ceci est ma carte de métro ECAMMANY.com/ny/subwaymap.gif