Если к «самому быстрому» относится количество потраченного вами времени, решение будет зависеть от того, какое программное обеспечение вам удобно и может использоваться в срочном порядке. Следующие замечания, следовательно, сосредоточены на идеях для достижения максимально быстрого времени вычислений .
Если вы используете постоянную программу, почти наверняка лучшее, что вы можете сделать, - это предварительно обработать полигоны для настройки структуры данных точка-полигон, такой как дерево KD или дерево квадрантов, производительность которого обычно будет O (log (V). ) * (N + V)) где V - общее количество вершин в многоугольниках, а N - количество точек, потому что структуре данных потребуется не менее O (log (V) * V) усилий для создания, а затем будет должны быть проверены для каждой точки при стоимости за точку O (log (V)).
Вы можете добиться значительно большего успеха, сначала установив сетку полигонов, используя предположение об отсутствии перекрытий. Каждая ячейка сетки либо целиком находится во внутренней части многоугольника (включая внутреннюю часть «универсального многоугольника»), и в этом случае пометьте ячейку идентификатором многоугольника, либо она содержит один или несколько ребер многоугольника. Стоимость этой растеризации, равная количеству ячеек сетки, на которые ссылаются при растеризации всех ребер, составляет O (V / c), где c - размер ячейки, но неявная константа в нотации big-O мала.
(Одним из достоинств этого подхода является то, что вы можете использовать стандартные графические процедуры. Например, если у вас есть система, которая (а) будет рисовать многоугольники на виртуальном экране, используя (b) отдельный цвет для каждого многоугольника и (с) позволяет Вы должны прочитать цвет любого пикселя, к которому хотите обратиться, у вас получилось.)
С этой сеткой предварительно экранируйте точки, вычисляя ячейку, содержащую каждую точку (операция 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. При его использовании общая вычислительная стоимость составляет O (log (V) * N), но неявная постоянная обычно намного меньше, чем при использовании стандартных процедур, из-за скорости O (N) предварительного скрининга.
20 лет назад я проверил этот подход (используя равномерно расположенные точки по всей Англии и на море и используя относительно грубую сетку из 400К ячеек, предлагаемых видеобуферами того времени) и получил ускорение на два порядка по сравнению с наилучшим опубликованным алгоритмом, который я мог находить. Даже когда полигоны маленькие и простые (например, треугольники), вы практически уверены в ускорении на порядок.
По моему опыту, вычисления были настолько быстрыми, что вся операция была ограничена скоростями ввода-вывода данных, а не процессором. Предвидя, что ввод-вывод может стать узким местом, вы достигнете очень быстрых результатов, сохранив точки в максимально сжатом формате, чтобы минимизировать время чтения данных. Также подумайте о том, как следует хранить результаты, чтобы можно было ограничить запись на диск.