Comment puis-je tester si un polygone est monotone par rapport à une ligne arbitraire?

16

Définition : Un polygone P dans le plan est appelé monotone par rapport à une droite L , si chaque ligne orthogonale à L coupe P au plus deux fois.

Étant donné un polygone P , est-il possible de déterminer s'il existe une ligne L telle que le polygone P soit monotone par rapport à L ? Si oui, comment?

Auparavant, j'ai posé une question connexe (où j'ai demandé comment déterminer si un polygone est monotone par rapport à une ligne particulière), mais maintenant je m'intéresse au cas où L n'est pas donné ou spécifié à l'avance.

com
la source
Pourquoi ne pas simplement faire pivoter / décaler le système de coordonnées de telle sorte que L devienne l' axe des x puis réexécuter l'ancien algorithme? Le travail supplémentaire devrait être gérable dans O(1) .
HdM
4
@HdM: la ligne L n'est pas indiquée comme entrée.
Tsuyoshi Ito

Réponses:

16

C'est possible.

Considérez votre polygone et considérez les sommets "concaves". Ils définissent exactement les lignes qui intersecteront le polygone plus de deux fois. Dans la figure suivante, j'ai marqué les intervalles (en rouge) des angles interdits. Si vous les assemblez et voyez un trou dans le disque rouge, alors il y a des angles autorisés (en bleu). Le polygone est alors monotone par rapport à toute ligne de pente - 1 / tan δ (en vert).δ1/tanδ

Astéroïdes

Maintenant l'algorithme.

Soit le i ème sommet du polygone. Calculez d'abord l'angle absolu α i du bord ( v i v i + 1 ) et l'angle intérieur β i du sommet v i . Utilisez la fonction disponible dans tous les bons langages de programmation.vi=(xi,yi)iαi(vivi+1)βiviatan2

β i = α i + 1 - α i + { 0  si  α i + 1α i 2 π  si  α i + 1 < α i

αi=atan2(yi+1yi,xi+1xi)
βi=αi+1αi+{0 if αi+1αi2π if αi+1<αi

Inversez l'ordre des sommets s'ils ne sont pas dans le sens antihoraire, c'est-à-dire si n'est pas négatif. ( s = - 2 π : dans le sens antihoraire, s = 2 π : dans le sens horaire).s=iβinπs=2πs=2π

Ce qui suit ne concerne que les angles intérieurs supérieurs à π, c'est-à-dire β j > π . Les rouges sur ma photo. Le but est de trouver un angle δ qui n'est pas dans j [ α j + 1 , α j ] modulo π . A savoir tel que pour tout j tel que β j > π :mπβj>πδj[αj+1,αj]πjβj>π

( α j < δ < α j + 1 )  si  α j < α j + 1

(δ<αj+1αj<δ) if αj+1<αj
(αj<δ<αj+1) if αj<αj+1

est ici la valeur normalisée de α j dans [ 0 , π ) . Le deuxième cas correspond à un intervalle qui dépasse π (donc cette fois δ doit être "à l'intérieur").αjαj[0,π)πδ

Il existe probablement un moyen plus rapide de le faire, mais l'un dans consiste à trier les valeurs α j  mod  π en γ 1 , γ m et à tester pour δ{ γ 1O(n2)αj mod πγ1,γmδ{γ12,γ1+γ22,,γm1+γm2,γm+π2}

δL1/tanδP

jmad
la source
Quel logiciel avez-vous utilisé pour faire cette illustration?
jojman
@jojman Je ne me souviens pas mais ce devait être GIMP, je ne me souviens d'aucun autre programme que j'aurais utilisé à l'époque.
jmad