寻找网格多边形的所有内部网格点,可以利用以下观察结果:
1. 对于每个内部网格点 (x,y),(x,y+0.5) 和 (x,y-0.5) 也是内部点。
2. 由 y=n+0.5 定义的线与网格多边形有简单的交点。
这导致以下算法:
1. 作为前提条件,需要所有非水平(即垂直和对角线)多边形边缘,实际上只需要每个(第二个)中间行的升序中心的 x 坐标。
2. 在每个第二个水平 "中间线",即 y=2n+0.5 处扫描网格,其中 n 是足够范围的整数,使得多边形被 "覆盖",请参见 scetch 中的蓝色线。
3. 从左侧开始,检测与多边形的所有交点(即非水平边缘)和所有形式为 (m,2n+0.5) 的内部点,参见红色和绿色圆圈(这是通过迭代边缘中心的 x 坐标完成的)。
4. 如果垂直网格邻居 (m,2n) 和 (m,2n+1) 不在边界上,则内部点 (m,2n+0.5) 的垂直网格邻居 (m,2n) 和 (m,2n+1) 也是内部点,参见 scetch 中的绿色点。
以下是一些伪代码(受 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)