Якщо "найшвидший" включає кількість витраченого вами часу, рішення залежатиме від того, яке програмне забезпечення вам подобається і яке ви можете використовувати оперативно. Наступні зауваження, отже, зосереджуються на ідеях для досягнення найшвидшого часу для обчислень .
Якщо ви використовуєте консервовану програму, майже напевно найкраще, що ви можете зробити, це попередньо обробити багатокутники, щоб створити структуру даних "багато в полігоні", наприклад, дерево KD або квадрати, продуктивність яких зазвичай буде O (журнал (V ) * (N + V)), де V - загальна кількість вершин у багатокутниках, а N - кількість точок, оскільки структура даних потребує принаймні зусиль O (log (V) * V) для створення, а потім буде повинні бути зондовані для кожної точки за вартістю за бал O (log (V)).
Можна зробити набагато краще, спершу склавши багатокутники, використовуючи припущення про відсутність перекриттів. Кожна клітинка сітки або повністю знаходиться у внутрішній частині багатокутника (включаючи внутрішню частину "універсального багатокутника"), і в цьому випадку комірка позначає ідентифікатором полігона, або ж вона містить один або більше країв полігону. Вартість цієї растерізації, що дорівнює кількості осередків сітки, на які посилається при растерізації всіх ребер, становить O (V / c), де c - розмір комірки, але неявна константа в нотації big-O невелика.
(Одна краса цього підходу полягає в тому, що ви можете використовувати стандартні графічні підпрограми. Наприклад, якщо у вас є система, яка (а) малює полігони на віртуальному екрані, використовуючи (b) виразний колір для кожного багатокутника і (c) дозволяє ви маєте читати колір будь-якого пікселя, до якого ви хочете звернутися, ви це зробили.)
Коли ця сітка на місці, попередньо екранізуйте точки, обчисливши комірку, що містить кожну точку (операція O (1), що вимагає лише декількох годин). Якщо точки не згруповані навколо меж полігона, це, як правило, залишатиме лише близько точок O (c) з неоднозначними результатами. Таким чином, загальна вартість побудови сітки та попереднього екранування становить O (V / c + 1 / c ^ 2) + O (N). Вам потрібно використовувати якийсь інший метод (наприклад, будь-який із рекомендованих до цього часу) для обробки решти точок (тобто тих, які близькі до меж багатокутника), вартістю O (log (V) * N * c) .
Оскільки c стає все менше, то менше та менше точок буде знаходитися в одній осередку сітки з ребром, і тому все менше та менше потребуватиме подальшої обробки O (log (V)). Протистояти цьому є необхідність зберігання осередків сітки O (1 / c ^ 2) і витрачати час O (V / c + 1 / c ^ 2) на растрування полігонів. Тому буде оптимальний розмір сітки c. Використовуючи це, загальні обчислювальні витрати являють собою О (балці (V) * N) , але неявна константа , як правило , способі менше , ніж при використанні консервованих процедур, пов'язаних зі швидкістю O (N) від попереднього скринінгу.
20 років тому я перевірив цей підхід (використовуючи рівномірно розташовані точки по всій Англії та на узбережжі та використовуючи відносно сиру сітку з близько 400 К осередків, запропонованих відеобуферами того часу) і отримав два порядки збільшення швидкості порівняно з найкращим опублікованим алгоритмом, який я міг знайти. Навіть коли багатокутники невеликі та прості (як трикутники), ви практично впевнені в порядку прискорення.
На мій досвід, обчислення були настільки швидкими, що вся операція була обмежена швидкістю вводу / виводу даних, а не процесором. Передбачаючи, що введення-виведення може бути вузьким місцем, ви доможетеся найшвидших результатів, зберігаючи точки у максимально стисненому форматі, щоб мінімізувати час читання даних. Також подумайте, як слід зберігати результати, щоб ви могли обмежити записи на диску.