【问题标题】:Point in convex polygon凸多边形中的点
【发布时间】:2013-04-25 21:33:00
【问题描述】:

我正在尝试创建一个函数,如果给定的 (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)

有人知道原因吗? 谢谢!

【问题讨论】:

标签: python polygon point-in-polygon


【解决方案1】:

在您遇到问题的特定情况下是特殊的: 多边形 = [(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

【讨论】:

  • 嗯,你说得有道理。但是我尝试了带有(5,8)的“沙漏”形状,它应该在沙漏中,因为它在两条线的交叉点上方,在上三角形内部。结果:也说“假”... :(
  • 哇,你知道你的工作! :) 现在我明白了它是如何工作的......谢谢!非常感谢您的图片!
  • 处理这种极端情况的代码链接似乎已损坏。请修复。
【解决方案2】:

9,0 不在多边形[(0,10),(10,10),(10,0),(0,0)] 的边上。根据您的算法的具体情况,可以考虑精确位于边缘的点。

【讨论】:

  • 好的,但是如果我尝试使用 (9,9),并修改多边形点的顺序:FROM [(0,10),(10,10),(10,0) ,(0,0)] TO [(0,0),(0,10),(10,0),(10,10)] 它仍然不起作用,只有给定的顺序....
【解决方案3】:

对于具有大量点的多边形,通常需要先检查点是否位于边界框之外:

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 webpages 之一找到很多处理多边形和网格的算法。

不过,对于其中许多算法,使用 numpy 是值得的,因为必须针对 poly 数组中的每个点执行许多步骤。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-11
    • 2013-05-26
    • 2011-05-09
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多