Se "mais rápido" inclui o montante de seu tempo que é gasto, a solução vai depender do que o software que você está confortável com e pode usar de forma expedita. As observações a seguir, conseqüentemente, se concentram em idéias para alcançar os tempos de computação mais rápidos possíveis .
Se você usar um programa fixo, quase certamente o melhor que poderá fazer é pré-processar os polígonos para configurar uma estrutura de dados point-in-polygon, como uma árvore KD ou quadtree, cujo desempenho normalmente será O (log (V ) * (N + V)) onde V é o número total de vértices nos polígonos e N é o número de pontos, porque a estrutura de dados exigirá pelo menos O (log (V) * V) esforço para criar e, em seguida, deve ser sondado para cada ponto a um custo por ponto O (log (V)).
Você pode obter um desempenho substancialmente melhor primeiro agrupando os polígonos, explorando a suposição de que não há sobreposições. Cada célula da grade está inteiramente no interior de um polígono (incluindo o interior do "polígono universal"); nesse caso, rotule a célula com o ID do polígono ou então contenha uma ou mais arestas de polígono. O custo dessa rasterização, igual ao número de células de grade referenciadas durante a rasterização de todas as arestas, é O (V / c), em que c é o tamanho de uma célula, mas a constante implícita na notação O-grande é pequena.
(Uma vantagem dessa abordagem é que você pode explorar rotinas gráficas padrão. Por exemplo, se você tiver um sistema que (a) desenhe os polígonos em uma tela virtual usando (b) uma cor distinta para cada polígono e (c) permita para ler a cor de qualquer pixel que você queira endereçar, você o criou.)
Com essa grade instalada, faça uma pré-seleção dos pontos computando a célula que contém cada ponto (uma operação O (1) exigindo apenas alguns relógios). A menos que os pontos estejam agrupados em torno dos limites do polígono, isso normalmente deixará apenas cerca de O (c) pontos com resultados ambíguos. O custo total de construção da grade e pré-triagem é, portanto, O (V / c + 1 / c ^ 2) + O (N). É necessário usar outro método (como qualquer um dos recomendados até agora) para processar os pontos restantes (ou seja, aqueles que estão próximos aos limites dos polígonos), a um custo de O (log (V) * N * c) .
À medida que c diminui, cada vez menos pontos estarão na mesma célula da grade com uma aresta e, portanto, cada vez menos exigirá o processamento subsequente de O (log (V)). Agindo contra isso é a necessidade de armazenar células da grade O (1 / c ^ 2) e gastar tempo O (V / c + 1 / c ^ 2) rasterizando os polígonos. Portanto, haverá um tamanho de grade ideal c. Utilizando-o, o custo computacional total é O (log (V) * N), mas a constante implícita é tipicamente muito menor do que o uso de procedimentos em lata, devido à velocidade O (N) da pré-triagem.
Há 20 anos, testei essa abordagem (usando pontos espaçados uniformemente em toda a Inglaterra e no exterior e explorando uma grade relativamente bruta de cerca de 400 mil células oferecidas pelos buffers de vídeo da época) e obtive duas ordens de aceleração de magnitude em comparação com o melhor algoritmo publicado que pude encontrar. Mesmo quando os polígonos são pequenos e simples (como triângulos), você tem praticamente a garantia de uma ordem de magnitude acelerada.
Na minha experiência, o cálculo foi tão rápido que toda a operação foi limitada pelas velocidades de E / S de dados, não pela CPU. Antecipando que a E / S pode ser o gargalo, você obteria os resultados mais rápidos armazenando os pontos no formato mais compactado possível para minimizar os tempos de leitura dos dados. Pense também em como os resultados devem ser armazenados, para que você possa limitar as gravações em disco.