Как найти, находится ли точка внутри многоугольника с помощью ракетки

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

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

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

1 ответов


я не буду публиковать код сейчас, потому что я не хочу решать домашнее задание/задание. Тем не менее, я опубликую некоторые подсказки.

посмотрите на следующее изображение:

Some vectors

как мы можем это знать C между краями OA и OB и D снаружи? Это просто: мы сравниваем некоторые углы: если угол между OC и OA меньше, чем угол между OB и OA тогда C явно ближе к OA чем OB есть.

теперь, как мы получаем угол, зная только некоторые векторы? Мы можем использовать монотонный Косинус: он уменьшается с увеличением аргумента. Таким образом, косинус угла между OC и OA - это больше, чем косинус угла между OB и OA, который, в свою очередь, больше, что косинус угла между OD и OA.

следующий шаг-выяснить, как вычислить Косинус. Продукт Vector dot помогает: это значение-косинус угла, в разы превышающий произведение длин операнда. То есть:

cos(OC; OA) = dotproduct(OC; OA) / (length(OA) * length(OC))

dotproduct в 2D прост:

dotproduct(OC; OA) = (C.x - O.x) * (A.x - O.x) + (C.x - O.x) * (A.x - O.x)

комбинируя все вышеперечисленное, вы должны иметь простой тест, чтобы проверить, находится ли ваша точка в той же ситуации, что и C или D: ближе к одному краю, чем предыдущий край или нет.

теперь вам придется повторить это для каждого края многоугольника, и все готово. Вы можете сделать это с помощью fold если тест является предикатом.

Примечание: это работает только, если многоугольник является выпуклым. Для вогнутого многоугольника вам нужно добавить больше тестов.

вторая записка: на рисунке, что произойдет, если D или C или как ниже OA линии? Подумайте об этом и проверьте, означает ли это еще некоторые изменения в приведенном выше fold метод.

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