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

aac*_*cid 5 algorithm point collision-detection

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

示例区域:

在此输入图像描述

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

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

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

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

cop*_*roc 4

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

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

这导致了以下算法:

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

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

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

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)
Run Code Online (Sandbox Code Playgroud)