Одним из решений является разделение вогнутого многоугольника на выпуклые сегменты, а затем использование ссылки cobbal.
Поскольку у вас действительно есть две разные фундаментальные проблемы, рассмотрели ли вы другие альтернативы проблеме теста попадания, например, используя дерево BSP? Вы можете ускорить это, уложив сетку поверх поли и построив дерево BSP для каждого квадрата сетки. Или kd-дерево с не более чем одним краем в каждом листе?
Edit: Я ellaborate на кД дерева (от скуки, даже если это может быть полезным для тех, кто):
KD-деревья обладают следующими свойствами:
- Они двоичные.
- Каждый нелистовой узел разбивает пространство вдоль плоскости, перпендикулярной оси, с одной стороны на каждого ребенка. Например. корень разбивает пространство на x < x0 и x> = x0
- Уровни деревьев разворачиваются по разным осям, т.е. Уровень 0 (корень) расщепляется перпендикулярно X, уровень 1 -> Y и т.д.
использовать это для полигона ударил обнаружения, построить дерево следующим образом:
- Выберите вершину, чтобы разделить вдоль. (Предпочтительно где-то близко к середине для сбалансированного дерева).
- Разделить другие вершины на два набора, по одному для каждой стороны раскола. Вышеупомянутая вершина не входит в любой набор.
- Поместите края в комплекты. Любое ребро, пересекающее разделительную линию, переходит в оба набора.
- Конструируйте детей рекурсивно из вышеуказанных групп.
Если разделенная вершина выбрана надлежащим образом, дерево должно иметь глубину, близкую к log (N), где N - количество вершин. Каждый листовой узел будет иметь не более одного края, проходящего через него. Чтобы сделать обнаружение попадания:
- Найдите лист, на который падает точка.
- Если в листе есть край, сравните точку с ним. Если нет, то должно быть ясно, находится ли точка внутри или снаружи (сохраняйте эту информацию в таких листьях при построении дерева).
Считаете ли вы, что «точка в полигоне» тяжелая? Большую часть времени это всего лишь тест «больше, чем» и/или «меньше» всех точек, из которых состоит многоугольник, и только в некоторых случаях проверка пересечения строк? Или...? –
Не уверен, что вы имеете в виду ... Я использую метод четного скрещивания для полупрямой (после проверки ограничивающего прямоугольника, конечно). Это заканчивается тестированием многих сторон, и если многоугольник имеет много сторон, он довольно медленный. –
Coud вы ссылаетесь на некоторые наборы данных, это звучит как нечто, что может быть интересно попробовать. –