Як і майже у всіх подібних питаннях, оптимальний підхід залежить від "випадків використання" та того, як представлені функції. Випадки використання, як правило, розрізняють (а) чи є багато або кілька об'єктів у кожному шарі та (b) чи допускає будь-який (або обидва) шари для попереднього обчислення деяких структур даних; тобто чи достатньо статичного та незмінного один чи обидва з них, щоб зробити інвестиції в попередні обчислення доцільними.
У цьому випадку це дає такі сценарії. Зазвичай бали динамічні: тобто вони не наводяться заздалегідь. (Якщо вони доступні заздалегідь, або в дуже великих групах, будуть доступні деякі оптимізації, засновані на їх сортування.) Нехай Q - кількість точок запиту, а P - кількість вершин багатокутника .
Векторні дані багатокутника
(1) Мало точок, кілька вершин багатокутника в тото . Використовуйте грубу силу, наприклад класичний алгоритм колючої лінії . Для будь-якого пристойного методу вартість становить O (P * Q), оскільки коштує O (1) час порівняння точки з краєм багатокутника, і всі подібні порівняння повинні бути виконані.
(2) Можливо, багато вершин багатокутника, але вони динамічні: кожного разу, коли в запиті використовується точка, всі полігони можуть змінитися. Знову використовуйте алгоритм грубої сили. Вартість все ще O (P * Q), яка буде великою, тому що P буде великою, але в цьому нічого не допоможе. Якщо зміни невеликі або контрольовані ( наприклад , багатокутники трохи змінюють форму або просто повільно рухаються навколо), можливо, ви зможете скористатися версією наступного рішення і знайти ефективний спосіб оновити структури даних під час зміни полігонів. Це, ймовірно, буде справою для оригінальних досліджень.
(3) Багато вершин вершин і статичних багатокутників (тобто шар багатокутника буде рідко змінюватися). Попередньо обчисліть структуру даних для підтримки пошуку (яка може базуватися на розгортанні рядків або алгоритмі квадратури ). Вартість попередніх обчислень для цих алгоритмів становить O (P * log (P)), але вартість запитів стає O (Q * log (P)), тому загальна вартість - O ((P + Q) * log ( П)).
Деякі вдосконалення доступні в особливих випадках , таких як
(a) Всі багатокутники опуклі ( попередня обробка полігонів може бути виконана швидше ),
(b) Усі інтер'єри полігонів роз'єднуються , і в цьому випадку ви можете вважати їх об'єднання як єдиний багатокутник (що дозволяє створювати прямо ефективні алгоритми, наприклад, засновані на тріангуляції, і
(c) Більшість багатокутників не дуже звивисті - тобто вони займають великі ділянки обмежувальних коробок - у цьому випадку ви можете зробити початковий тест лише на основі обмежувальних коробок, а потім уточнити це рішення. Це популярна оптимізація.
(г) Кількість балів велика. Сортування їх може покращити терміни. Наприклад, впроваджуючи алгоритм розгортки ліворуч на правий рядок з точкою в полігоні, ви б сортували точки за їх першою координатою, що дозволяє вам переміщати точки, одночасно переміщуючи їх по краях полігону. Мені невідомо, що така оптимізація була опублікована. Однак, опублікованим є виконання обмеженої тріангуляції об'єднання всіх точок і вершин багатокутника: після того, як триангуляція завершена, виявлення внутрішніх точок повинно бути швидким. Обчислювальна вартість буде масштабуватися як O (Q * log (Q) + (P + Q) * log (P + Q)).
Дані полігону растрових
Це неймовірно просто: розглядайте шар багатокутника як растровий бінарний індикатор (1 = всередині багатокутника, 0 = зовні). (Це може зажадати таблиці пошуку для конвертації растрових значень у внутрішні та зовнішні індикатори.) Кожен точковий зонд тепер потребує зусиль O (1) для індексації растрової комірки та зчитування її значення. Загальне зусилля - O (Q).
В загальному
Приємне гібридне рішенняу випадку багатьох статичних векторних багатокутників (векторний випадок 3 вище) спочатку є растерізація полігонів, можливо, навіть із грубою роздільною здатністю, на цей раз розрізняючи будь-які клітини, що перетинають будь-яку частину межі полігона (дайте їм значення 2, скажімо) . Використання растрового зонда (вартість: O (1)) зазвичай призводить до визначеної відповіді (точка, як відомо, всередині або зовні), але іноді призводить до невизначеної відповіді (точка падає в клітинку, через яку хоча б один край проходи), і в цьому випадку робиться більш дорогий векторний запит O (log (P)). Цей метод вимагає певних додаткових витрат на зберігання растру, але у багатьох випадках навіть невеликий растр (один МБ дозволить отримати растр 2000 на 2000 рік, який зберігає значення {0,1,2, null}) може надати величезні переваги в обчислювальний час . Асимптотично,