【问题标题】:find all inner grid points of a polygon made up from neighbouring grid points找到由相邻网格点组成的多边形的所有内部网格点
【发布时间】:2013-02-04 11:22:42
【问题描述】:

我有点列表(int x,int y)。 它们一起形成区域,我检查该区域是否已关闭,然后我需要获取由该区域内的所有位置形成的内部区域。

示例区域:

我唯一的想法是将这个区域转换为矢量并检查每个点是否在多边形内,计算多边形的交点轴的点。

但我认为这不是最有效的方法。

另一个想法是首先获取外部的所有点,我从角开始(如果角不是点列表的一部分,则 100% 为空),添加所有空的相邻点并重复。 那么所有不在外部且不在突出显示列表中的点都在内部。

但又一次,感觉有点麻烦......

【问题讨论】:

  • 听起来很像convex hull
  • 这些区域总是很简单,还是像字母 O 一样在里面有洞?
  • 1.你想找到有界图形的面积还是其中的点数? 2. 该区域关闭的具体含义是什么?这是否意味着它的形状要么平行于坐标线,要么形成 45 度。与他们的角度?
  • @Dukeling 谢谢,看起来这可能是解决方案,我仔细看看。
  • @AlexeyFrunze 里面可能有洞。

标签: algorithm collision-detection point


【解决方案1】:

要找到网格多边形的所有内部网格点,可以利用这些观察结果:

  1. 对于每个内部网格点 (x,y),(x,y+0.5) 和 (x,y-0.5) 也是内部点。
  2. y=n+0.5 定义的线与网格多边形有简单的交点

这导致以下算法:

  1. 作为先决条件,需要所有非水平(即垂直和对角线)多边形边,实际上每个(第二个)中间行只有中心的 x 坐标按升序排列。

  2. 每隔一个水平“中线”扫描网格,即y=2n+0.5,其中 n 来自足够的整数范围 s.t.多边形被“覆盖”,请参见草图中的蓝线。

  3. 从左边开始,所有与多边形的交点(即非水平边)和所有形式为 (m,2n+0.5) 的内部点都将被检测,请参见红色和绿色圆圈(这是通过迭代边缘中心的 x 坐标)
  4. 现在内点 (m,2n+0.5) 的垂直网格邻居 (m,2n) 和 (m,2n+1) 是内点,如果它们不在边界上,请参见草图中的绿色点.

这是一些伪代码(受 C++/python 启发 :-)):

list<Point> polygon; // given polygon as list of neighbouring grid points

// get centers of non-horizontal edges organized by line
map<int, set<float> > edgeCentersX; // for each scan line the x-coords of edges in ascending order

p_i = polygon[0]
yMin, yMax =  999999, -999999
for (i=1; i<polygon.size(); ++i)
    p_i1 = polygon[i] // next point after p_i
    if (p_i.x == p_i1.x)
        continue // horizontal edges can be ignored
    yMin_i = min(p_i.y, p_i1.y)
    if (yMin_i % 2 == 1)
        continue // we only need to look at each second mid-row
    if (yMin_i < yMin)
        yMin = yMin_i
    if (yMin_i > yMax)
        yMax = yMin_i
    cx = 0.5*(p_i.x+p_i1.x)
    edgeCentersX[yMin_i].insert(cx) // store edge center (yMin_i+0.5, cx)
    p_i = p_i1

list<Point> innerPoints
for (y=yMin; y<= yMax; y+=2)
    inside = false
    cx_i = edgeCentersX[y][0]
    for (i=1; i<edgeCentersX[y].size(); ++i)
        cx_i1 = edgeCentersX[y][i]
        inside = !inside
        if (!inside)
            continue
        for (x=floor(cx_i)+1; x<cx_i1; ++x)
            pLower = Point(y,x)
            if (!polygon.contains(pLower))
                innerPoints.append(pLower)
            pUpper = Point(y+1,x)
            if (!polygon.contains(pUpper))
                innerPoints.append(pUpper)

【讨论】:

  • 谢谢!,看起来很有趣,今晚将与 graham 扫描算法(如 Dukeling 建议的)一起测试它,看看哪种效果更好。您的解决方案看起来更简单,看看它是否适用于所有情况。
【解决方案2】:

Pick's theorem 可能是您正在寻找的公式。它允许对角为网格点(即具有整数坐标)的多边形的面积进行相当简单的计算。

【讨论】:

  • 对不起,我可能问错了问题,我不需要数学计算面积,我需要获取里面的点列表。
  • 好的,里面的点数正是 Pick 公式的输入之一 :-) 所以你会遇到同样的问题。
猜你喜欢
  • 2018-02-14
  • 1970-01-01
  • 2022-08-18
  • 1970-01-01
  • 2015-03-06
  • 2014-02-06
  • 1970-01-01
  • 1970-01-01
  • 2017-10-27
相关资源
最近更新 更多