Нахождение диагоналей многоугольника

Учитывая вогнутый многоугольник (без самопересечений), узлы которого расположены по часовой стрелке, как мы можем определить все его внутренние диагонали (те, которые находятся внутри многоугольника)?

Меня интересует решение, в котором не используются триггерные функции.

Предыстория и то, что я пробовал:

В моем классе вычислительной геометрии нам дали следующий алгоритм, чтобы проверить, является ли [pi, pj] внутренней диагональю многоугольника p0, p1, ... pn-1:

  1. Проверить, пересекает ли [pi, pj] край многоугольника, который не примыкает к нему. Если да, то это не внутренняя диагональ. Если нет, переходите к шагу 2.
    1. if pi is a convex point (pi-1, pi, pi+1 make a right turn), then [pi, pj] is an inner diagonal iff pi, pj, pi+1 and pi, pi-1, pj make a left turn.
    2. если pi не является выпуклой точкой (pi-1, pi, pi+1 повернуть налево), то [pi, pj] - внутренняя диагональ, если pj, pj-1, pi повернуть налево.

Этот алгоритм был дан нам для алгоритма триангуляции, включающего обрезку ушей. Я реализовал этот алгоритм, и, похоже, он там отлично работает, но загвоздка в том, что алгоритм обрезки ушей использует только диагонали формы [pi, pi+2].

Однако рассмотрим алгоритм триангуляции методом грубой силы, который выбирает все непересекающиеся диагонали. Используя то, что я описал как подпрограмму для проверки внутренних диагоналей (вместе с методом пересечения сегментов), я получаю следующий результат:

alt text

Легко проверить, что опубликованный мной алгоритм отклоняет внутреннюю диагональ [3, 6], хотя на самом деле это не должно:

3 не является выпуклой точкой, и 6, 5, 3 делает поворот направо, а не налево, поэтому он отклоняется.

Обратите внимание, что при использовании алгоритма обрезки ушей этот многоугольник триангулируется правильно.

Мне интересно, как этот алгоритм можно адаптировать для обнаружения всех диагоналей в многоугольнике. Мне не удалось заставить его работать.

Я также обнаружил другие проблемы с этим методом, такие как многоугольники, для которых нарисованы внешние диагонали. Опять же, они работают с алгоритмом обрезки ушей. Однако нам никогда не говорили, что этот метод применим только к особой форме диагоналей, поэтому я ищу пояснений.

Примечание. Я не мог решить, размещать ли это на math.stackexchange.com или здесь, поскольку вычислительная геометрия в некоторой степени связана как с программированием, так и с математикой, однако я чувствовал, что программисты могут быть более знакомы с такими алгоритмами, чем математики, поскольку кто-то, вероятно, действительно реализовал это в какой-то момент.


person IVlad    schedule 07.12.2010    source источник
comment
Пожалуйста, проверьте. Кажется очень похожим на этот заголовок stackoverflow.com/questions/693837/   -  person Dr. belisarius    schedule 07.12.2010
comment
Я подозреваю, что у описанного вами алгоритма есть дополнительные условия (даже для точек вида [p, p + 2]), потому что легко построить примеры счетчиков, когда алгоритм говорит, что он внутренний, но многоугольник пересекает отрезок линии - например шестиугольник с единственной вогнутой вершиной, проверка [p-1, p + 1], где p - на 3 вершины от вогнутой вершины.   -  person lijie    schedule 07.12.2010
comment
@lijie - не совсем, это будет рассмотрено на шаге 1 алгоритма. @belisarius - проверю.   -  person IVlad    schedule 07.12.2010
comment
2.1. похоже, это проверка того, что pj находится внутри выпуклого угла, определяемого pi-1, pi, pi + 1. В таком случае не может 2.2. быть модифицированным таким образом, чтобы он проверял, что pj находится вне выпуклого угла, определяемого формулами pi + 1, pi, pi-1?   -  person lijie    schedule 08.12.2010
comment
@belisarius - Я проверил эти вопросы, но не смог заставить опубликованное решение работать во всех случаях, поэтому я хотел бы оставить это открытым на некоторое время. @@ lijie - Я пытался, но смог найти контрпримеры для всех своих попыток. Есть предложения, как это сделать?   -  person IVlad    schedule 08.12.2010
comment
@IVlad Хорошо. Я не был уверен, это было всего лишь предложение.   -  person Dr. belisarius    schedule 08.12.2010
comment
о ... если я изменю 2.2, как предложено (если pi - вогнутая точка, то [pi, pj] будет внутренней диагональю тогда и только тогда, когда pi, pj, pi-1 или pi, pi + 1, pj поверните направо) какой контрпример? (обратите внимание на или вместо и)   -  person lijie    schedule 10.12.2010
comment
@lijie - не могу найти. Я буду продолжать поиски, но до тех пор, возможно, вы захотите опубликовать это в качестве ответа ...   -  person IVlad    schedule 11.12.2010


Ответы (3)


Раздел 2.1 алгоритма выглядит так, как будто это проверка того, что pj находится «внутри» выпуклого угла, определенного pi-1, pi, pi+1.

Раздел 2.2 может быть получен из Раздела 2.1, так что он проверяет, что pj не находится во «внутренней части» выпуклого угла, определенного pi+1, pi, pi-1. Это в основном NOT (pi, pj, pi-1 and pi, pi+1, pj make a left turn) == pi, pj, pi-1 or pi, pi+1, pj make a right turn.

Таким образом, весь пункт будет следующим: «если pi - вогнутая точка, то [pi, pj] - это внутренняя диагональ, если и только pi, pj, pi-1 или pi, pi+1, pj (или оба) повернут направо.

person lijie    schedule 11.12.2010

Несколько примечаний:

1) Легко проверить, является ли диагональ внутренней, сравнив углы (например, для диагонали 4-6 угол 3-4-5 больше, чем угол 3-4-6, поэтому диагональ внутренняя). Я уверен, что это можно упростить с помощью векторного произведения, но моя математика не так хороша.

2) Чтобы проверить, не пересекается ли конкретная внутренняя диагональ с другими ребрами, вы можете проверить, находятся ли точки многоугольника на ожидаемой стороне. Пример: если мы попробуем диагональ 1-4, точки 2 и 3 должны быть с одной стороны, а точки 5, 6 и 7 - с другой. Если это не так, то диагональ пересекает ребро.

person ruslik    schedule 07.12.2010

Обратите внимание, насколько это будет эффективно, но вы можете вычислить выпуклую оболочку, а затем получить список многоугольников («исключенных» многоугольников), которые находятся в выпуклой оболочке, но не в исходном многоугольнике. (В вашем примере выпуклая оболочка будет иметь вершины 1,2,4,5,7, так что исключенные многоугольники будут (2,3,4), (5,6,7).) Тогда требуемые диагонали будут диагонали исходного многоугольника, которые не пересекают ни один из исключенных многоугольников. Но учтите, что исключенные многоугольники могут не быть треугольниками, а могут и не быть выпуклыми, поэтому проверка пересечения линий может быть неудобной.

person dmuir    schedule 08.12.2010