找到由相邻网格点组成的多边形的所有内部网格点

时间:2013-02-04 11:22:43

标签: algorithm collision-detection point

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

示例区域:

enter image description here

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

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

其他想法是首先得到所有外面的点,我从角落开始(如果角落不是点列表的一部分,那么是100%为空),添加所有空的并重复的邻居点。 那么所有不在外面并且不在突出显示列表中的点都在里面。

但同样,感觉有些麻烦...

2 个答案:

答案 0 :(得分:4)

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

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

    这导致以下算法:

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

      < / LI>
    2. 在每个第二水平“中线”扫描网格,即y=2n+0.5,其中n来自足够的整数范围。多边形是“覆盖”的,请参见scetch中的蓝线。

    3. 从左边开始所有与多边形的交点(即非水平边缘)和形式的所有内点(m,2n + 0.5)都要检测,请看红色和绿色圆圈(这是由迭代边缘中心的x-coors
    4. 现在垂直网格邻居(m,2n)和(m,2n + 1)内点(m,2n + 0.5)是内点,如果它们不在边界上,请参见scetch中的绿点
    5. AlgoScetch_innerPoints

      这是一些伪代码(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)
      

答案 1 :(得分:0)

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