指向凸多边形

时间:2013-05-01 20:13:46

标签: python polygon point-in-polygon

如果给定的(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)

有人知道原因吗? 谢谢!

3 个答案:

答案 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

The code above draws this image.

答案 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数组中的每个点完成许多步骤。