Znalazłem dwie główne metody sprawdzania, czy punkt należy do wielokąta. Jedną z nich jest metoda ray tracingu wykorzystana jako here, która jest najbardziej zalecaną odpowiedzią, druga wykorzystuje matplotlib path.contains_points
(co wydaje mi się nieco niejasne). Będę musiał ciągle sprawdzać wiele punktów. Czy ktokolwiek wie, czy któryś z tych dwóch jest bardziej zalecany niż drugi, czy są jeszcze lepsze trzecie opcje?Jaki jest najszybszy sposób sprawdzenia, czy punkt znajduje się wewnątrz wielokąta w pytonie?
UPDATE:
Sprawdziłem dwie metody i matplotlib wygląda o wiele szybciej.
from time import time
import numpy as np
import matplotlib.path as mpltPath
# regular polygon for testing
lenpoly = 100
polygon = [[np.sin(x)+0.5,np.cos(x)+0.5] for x in np.linspace(0,2*np.pi,lenpoly)[:-1]]
# random points set of points to test
N = 10000
points = zip(np.random.random(N),np.random.random(N))
# Ray tracing
def ray_tracing_method(x,y,poly):
n = len(poly)
inside = False
p1x,p1y = poly[0]
for i in range(n+1):
p2x,p2y = poly[i % n]
if y > min(p1y,p2y):
if y <= max(p1y,p2y):
if x <= max(p1x,p2x):
if p1y != p2y:
xints = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
if p1x == p2x or x <= xints:
inside = not inside
p1x,p1y = p2x,p2y
return inside
start_time = time()
inside1 = [ray_tracing_method(point[0], point[1], polygon) for point in points]
print "Ray Tracing Elapsed time: " + str(time()-start_time)
# Matplotlib mplPath
start_time = time()
path = mpltPath.Path(polygon)
inside2 = path.contains_points(points)
print "Matplotlib contains_points Elapsed time: " + str(time()-start_time)
, zawierające
Ray Tracing Elapsed time: 0.441395998001
Matplotlib contains_points Elapsed time: 0.00994491577148
Bez różnicy względnej otrzymano stosując jeden trójkąt zamiast wieloboku 100 stron. Będę również sprawdzić zgrabna ponieważ wygląda pakiet właśnie poświęcony tego rodzaju problemów
Ponieważ implementacja programu matplotlib to C++, prawdopodobnie można oczekiwać, że będzie on szybszy. Biorąc pod uwagę fakt, że matplotlib jest bardzo szeroko stosowany i jest to bardzo podstawowa funkcja - prawdopodobnie można bezpiecznie założyć, że działa poprawnie (nawet jeśli może wydawać się to "niejasne"). Last but not least: Dlaczego nie po prostu go przetestować? – sebastian
Zaktualizowałem pytanie testem, zgodnie z przewidywaniami, matplotlib jest znacznie szybsze. Byłem zaniepokojony, ponieważ matplotlib nie jest najsławniejszą odpowiedzią w różnych miejscach, na które patrzyłem, i chciałem wiedzieć, czy coś przeoczyłem (lub jakiś lepszy pakiet). Również matplotlib wyglądał na dużego faceta na takie proste pytanie. –