如果给定的(x,y)点位于凸多边形内,我正在尝试创建一个返回True
的函数。我试图使它没有numpy或任何类似的导入,只是纯python代码。
我已经找到了一个示例解决方案,乍一看似乎没问题,但它无法正常工作,我无法弄清楚原因。代码如下:
def point_in_poly(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
如果我测试(9,9),对于下面的多边形,它会给我True
:
polygon = [(0,10),(10,10),(10,0),(0,0)]
point_x = 9
point_y = 9
print point_in_poly(point_x,point_y,polygon)
但是当我改变多边形的点的顺序时,对于同一点,它给了我False
:
polygon = [(0,0), (0,10), (10,0), (10,10)]
point_x = 9
point_y = 9
print point_in_poly(point_x,point_y,polygon)
有人知道原因吗? 谢谢!
答案 0 :(得分:5)
在特殊情况下,您遇到的问题很特殊: polygon = [(0,0),(0,10),(10,0),(10,10)]
更改多边形中点的顺序会对算法产生重大影响。
如果在图形上绘制多边形,您将看到水平沙漏形状。多边形边框重叠。在地理空间分析中,不允许这种重叠,因为在视觉和逻辑上,您现在有两个具有公共交叉点的闭合多边形。顺便说一下,大多数地理空间软件也不能很好地处理三角形。
在这种情况下,9,9处的点会欺骗上面方法中使用的光线投射算法,因为它可以轻松地两次越过双面多边形边界。
请运行以下代码以查看发生了什么。 (9,9)在线,这个算法没有考虑到它。 (5,8)在外面:
import turtle as t
polygon = [(0,0), (0,100), (100,0), (100,100)]
t.goto(0,0)
fp = None
for p in polygon:
t.goto(p)
if not fp: fp=p
t.goto(fp)
t.up()
t.goto(90,90)
t.write("90,90")
t.dot(10)
t.goto(50,80)
t.write("50,80")
t.dot(10)
t.done()
此代码处理(9,9)边缘情况: http://geospatialpython.com/2011/08/point-in-polygon-2-on-line.html
答案 1 :(得分:0)
点9,0
不在边缘的多边形[(0,10),(10,10),(10,0),(0,0)]
内。根据算法的具体情况,可以考虑精确地在边缘上的点。
答案 2 :(得分:0)
对于有很多积分的多边形,通常需要检查点是否首先落在边界框之外:
def point_in_poly(x, y, poly):
# Check bounding box first
xl = [p[0] for p in poly]
yl = [p[1] for p in poly]
if x < min(xl) or x > max(xl) or y < min(yl) or y > max(yl):
return False
# Now check all points.
您可以在Paul Bourke's webpage之一找到许多处理多边形和网格的算法。
对于很多这些算法,使用numpy是值得的,因为必须为poly
数组中的每个点完成许多步骤。