Возможно.
Считайте себя многоугольником и рассмотрите «вогнутые» вершины. Они точно определяют, какие линии будут пересекать многоугольник более чем в два раза. На следующем рисунке я отметил интервалы (красным) запрещенных углов. Если вы сложите их вместе и увидите дыру в красном диске, то есть разрешенные углы δ (синим цветом). В этом случае многоугольник является монотонным по отношению к любой линии наклона −1/tanδ (зеленым цветом).
Теперь алгоритм.
Пусть быть я й вершина многоугольника. Сначала вычисляют абсолютный угол α i ребра ( v i v i + 1 ) и внутренний угол β i вершины v i . Используйте функцию, доступную на всех хороших языках программирования.vi=(xi,yi)iαi(vivi+1)βiviatan2
β i = α i + 1 - α i + { 0, если α i + 1 ≥ α i 2 π, если α i + 1 < α я
αi=atan2(yi+1−yi,xi+1−xi)
βi=αi+1−αi+{02π if αi+1≥αi if αi+1<αi
Обратный порядок вершин, если они не в порядке против часовой стрелки, т. Е. Если не является отрицательным. ( s = - 2 π : против часовой стрелки, сs=∑iβi−nπs=−2π : по часовой стрелке).s=2π
Следующее только для внутренних углов больше, чем π, то есть β j > π . Красные на моей картинке. Цель состоит в том, чтобы найти угол δ, который не входит в ∪ j [ α j + 1 , α j ] по модулю π . А именно такой, что для всех j таких, что β j > π :mπβj>πδ∪j[αj+1,αj]πjβj>π
( α j < δ < α j + 1 ), если α j < α j + 1
(δ<αj+1∨αj<δ) if αj+1<αj
(αj<δ<αj+1) if αj<αj+1
где - здесь нормализованное значение α j в [ 0 , π ) . Второй случай соответствует интервалу, выходящему за пределы π (поэтому на этот раз δ должен быть «внутри»).αjαj[0,π)πδ
Вероятно, есть более быстрый способ сделать это, но в можно отсортировать значения α j mod π на γ 1 , … γ m и проверить δ ∈ { γ 1O(n2)αj mod πγ1,…γmδ∈{γ12,γ1+γ22,…,γm−1+γm2,γm+π2}
δL−1/tanδP