Получить произвольную точку внутри замкнутого 2D контура
Правила форума
Пожалуйста, ознакомьтесь с правилами данного форума
Пожалуйста, ознакомьтесь с правилами данного форума
-
- Маньяк
- Сообщения: 2803
- Зарегистрирован: 29 май 2003, 22:29
- Откуда: Магадан - Миссиссага
-
- Маньяк
- Сообщения: 4706
- Зарегистрирован: 20 янв 2005, 19:11
-
- Маньяк
- Сообщения: 2803
- Зарегистрирован: 29 май 2003, 22:29
- Откуда: Магадан - Миссиссага
Имеем плоский полигон. Замкнутый. Невыпуклый. Без дыр. Имеем набор точек P (вершин) с координатами x,y. Вершины хранятся в массиве. P, P[i+1] - ребро многоугольника.Zy писал(а):Слишком общий вопрос. Какого контура? Чем он описывается? Откуда известно, что замкнутый? В каком виде ты его имеешь? Уравнение? Набор точек? Границы?
Подробности, короче.
-
- Маньяк
- Сообщения: 4706
- Зарегистрирован: 20 янв 2005, 19:11
-
- Маньяк
- Сообщения: 4706
- Зарегистрирован: 20 янв 2005, 19:11
Что невыпуклый - это фигово. Вот тут посмотри, может, что подойдет:
http://program.rin.ru/razdel/html/905.html
http://program.rin.ru/razdel/html/905.html
- sz
- Маньяк
- Сообщения: 1266
- Зарегистрирован: 17 фев 2003, 19:34
Очень просто. Любая из вершин - однозначно принадлежит контуру. Если нужна произвольная точка, можно взять вершину.
А если говорить про алгоритм определения, внутри, или снаружи точка - то он очень простой. Провести вертикальную линию, определить сколько пересечений с ребрами сверху, и сколько снизу. Если нечетное, значит внутри, если четное, значит снаружи.
Если пересекает вершину - то особый случай. Нужно посмотреть, засчитывать пересечение, или нет. Если оба ребра справа, или слева от вертикальной линии, то не засчитывать, а если по разные стороны, то да. Если ребро совпадает с вертикальной линией, то рассмотреть предыдущее/следующее на предмет, с какой стороны. И так далее.
Получается O(n). Можно построить r-index по горизонтальным проекциям и искать пересечения по нему. Тогда O(lg(n)).
А если говорить про алгоритм определения, внутри, или снаружи точка - то он очень простой. Провести вертикальную линию, определить сколько пересечений с ребрами сверху, и сколько снизу. Если нечетное, значит внутри, если четное, значит снаружи.
Если пересекает вершину - то особый случай. Нужно посмотреть, засчитывать пересечение, или нет. Если оба ребра справа, или слева от вертикальной линии, то не засчитывать, а если по разные стороны, то да. Если ребро совпадает с вертикальной линией, то рассмотреть предыдущее/следующее на предмет, с какой стороны. И так далее.
Получается O(n). Можно построить r-index по горизонтальным проекциям и искать пересечения по нему. Тогда O(lg(n)).
-
- Маньяк
- Сообщения: 4706
- Зарегистрирован: 20 янв 2005, 19:11
- sz
- Маньяк
- Сообщения: 1266
- Зарегистрирован: 17 фев 2003, 19:34
Ну так, это примерно то же самое.Насколько я понял, нужно найти точку внутри, а не определить, является ли данная точка внутри
Например, берем первые две вершины. Проводим произвольную вертикальную прямую между ними. Считаем количество пересечений, как описано ранее. Ставим произвольную между самым верхним(нижним) и следующим сверху (снизу) пересечением. Она заведомо принадлежит.
Причем, не важно, выпуклая фигура, вогнутая, с дырками, без дырок..
- sz
- Маньяк
- Сообщения: 1266
- Зарегистрирован: 17 фев 2003, 19:34
-
- Маньяк
- Сообщения: 4706
- Зарегистрирован: 20 янв 2005, 19:11
- AlexANB
- Маньяк
- Сообщения: 2904
- Зарегистрирован: 17 фев 2003, 18:47
- Откуда: Ontario
Re: Получить произвольную точку внутри замкнутого 2D контура
Наружу надо из выбранной точки идти лучом до границ Вселенной и считать количество пересечений с границами исходного полигона.vg писал(а):Как?
Если нечетное -- мы внутри. Если четное -- мы снаружи.
-
- Маньяк
- Сообщения: 4706
- Зарегистрирован: 20 янв 2005, 19:11
-
- Маньяк
- Сообщения: 2803
- Зарегистрирован: 29 май 2003, 22:29
- Откуда: Магадан - Миссиссага
Спасибо за ответ. Похоже будет работать. Контр-пример не находится.Старина Зотин писал(а):Ну так, это примерно то же самое.Насколько я понял, нужно найти точку внутри, а не определить, является ли данная точка внутри
Например, берем первые две вершины. Проводим произвольную вертикальную прямую между ними. Считаем количество пересечений, как описано ранее. Ставим произвольную между самым верхним(нижним) и следующим сверху (снизу) пересечением. Она заведомо принадлежит.
Причем, не важно, выпуклая фигура, вогнутая, с дырками, без дырок..
Маленькое уточнение по вашему алгоритму. Здесь (как описано выше) число пересечений всегда будет чётным. Так, что считать число пересечений нет необходимости. (Это делают в алгоритмах определения принадлежности точки к внутренней области многоугольника, только используют не прямую, а луч.)
Ну и для того, чтобы заработало практически, надо добавим анализ вырожденных случаев ( ребро колинеарно прямой, и тд) ... но это и так всем понятно.
ПС. Куда бутылку нести?

-
- Маньяк
- Сообщения: 4706
- Зарегистрирован: 20 янв 2005, 19:11
- ajkj3em
- Маньяк
- Сообщения: 2063
- Зарегистрирован: 12 ноя 2006, 06:53