D'abord, vous devez calculer quels segments de la ligne de coupe appartiennent aux internes de votre polygone d'origine. C'est un problème classique et sa solution est simple. Étant donné que vos points c1, c2, c3 ... c6
sont disposés le long de la ligne dans exactement cet ordre, les segments c1-c2
, c3-c4
etc appartiendront toujours aux polygones internes (*).
Maintenant, nous pouvons construire un algorithme récursif simple pour couper des polygones. Étant donné votre grand tableau d'entrée, {a, c1, b, c4, c, c5, d, c6, e, c3, f, c2}, commencez à partir de n'importe quel point de polygone, par exemple, b
; ajoutez-le au tableau result
. Traverse le tableau d'entrée vers l'avant. Si vous rencontrez
- noeud polygone d'habitude, pousser à un tableau
result
.
ck
nœud, où k
est impair, recherchez c(k+1)
et continuez à traverser à partir de sa position.
- noeud
ck
, où k
est encore, chercher c(k-1)
, sauter à sa position et continuer néanmoins traverser vers l'avant.
Pour deux derniers cas, ajoutez ces noeuds dans l'ordre que vous rencontrez à result
tableau.Ajouter ck
noeud pour définir cut
, et ajouter un autre noeud (c(k+1)
ou c(k-1)
, selon ce que vous avez) dans un ensemble global done
.
Si vous devez aller au-delà du dernier élément, passez au premier élément du tableau d'entrée.
Tôt ou tard, vous rencontrerez le nœud initial que vous avez traversé. Maintenant, dans le tableau result
, vous avez un polygone que vous avez coupé. Souviens toi. Répétez la procédure récursivement, à partir de la position de chaque nœud appartenant à cut
et n'appartenant pas à l'ensemble global done
.
Voilà la solution que je vois. Mais c'est la géomancie computationnelle, donc cela peut devenir un peu plus complexe qu'il n'y paraît.
Pour notre exemple, commencer à partir b
:
done={}
, partir b
. Après la première passe, vous obtiendrez result=[b,c4,c3,f,c2,c1]
, cut={c4,c2}
, done={c3,c1}
; Recurse à c4
et c2
nœuds.
done={c3;c1}
, à partir de c4
(récursivité à partir de 1). Après ce passage, vous aurez result=[c4,c,c5,c6,e,c3,c4]
, cut={c5,c3}
, done+={c6,c4}
; Recurse à c5
.
done={c3;c1;c4;c6}
, à partir de c2
(récursivité à partir de 1). Après ce passage, vous aurez result=[c2,a,c1]
, cut={c1}
, done+={c2}
; Ne pas recurse à c1
, car il est en done
ensemble;
done={c3;c1;c4;c6;c2}
, à partir de c5
(récursivité à partir de 2). Après ce passage, vous aurez result=[c5,d,c6]
, cut={c5}
, done+={c6}
; Ne pas recurse à c5
, car il est en done
ensemble;
Voila - vous obtenez 4 polygones dont vous avez besoin.
(*) Notez qu'il exige une plus grande représentation "mathématique" de la ligne. Par exemple, si l'un des sommets de polygone est sur la ligne, le sommet doit être doublé, c'est-à-diresi c
point était un peu plus proche du côté droit et sur la ligne rouge, la ligne aurait [c1, c2, c3, c, c, c6]
points, et le tableau de polygones serait [a, c1, b, c, c, c, d, c6, e, c3, f, c2]
.
Parfois (pas dans cet exemple), cela peut conduire à couper des polygones "vides", tels que [a, a, a]
. Si vous n'en avez pas besoin, vous pouvez les éliminer à un stade avancé. Quoi qu'il en soit, c'est une géométrie computationnelle avec un nombre immense de cas de frontière. Je ne peux pas tous les inclure dans une seule réponse ...
Quand j'ai vu votre image j'ai finalement compris la sortie. Cependant, je ne pense pas, compte tenu de cette entrée, l'ordinateur peut en quelque sorte magiquement deviner que les coordonnées C appartiennent tous ensemble. Donc, je pense qu'en dehors des coordonnées du polygone, vous avez également besoin d'un tableau d'entrée separe spécifiant lequel de ces indices sont les indices à couper.Plus logique serait: un polygone, et 1 vecteur qui définit la ligne de coupe – Toad
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 l'image, mais stackoverflow ne me permet pas encore de poster des photos :( – sulf
J'ai ajouté aussi un algorithme de pseudocode, que j'ai utilisé pour savoir – sulf