爲了找到網格多邊形的所有內部網格點,可以利用這些觀察:
- 針對每個內部網格點(X,Y)還(X,Y + 0.5)和(x軸,y軸0.5)是內點。
- 由
y=n+0.5
限定的線具有與網格多邊形
這導致下面的算法簡單交點:
作爲先決條件人們需要所有非水平(即垂直和對角線)多邊形邊緣,實際上每個(第二)中間行只有中心的x座標以升序排列。
在每個第二水平「中線」即y=2n+0.5
處掃描網格,其中n來自足夠範圍的整數s.t.多邊形是「覆蓋」的,參見scetch中的藍線。
- 從左邊開始檢測與多邊形的所有交點(即非水平邊)和形式(m,2n + 0.5)的所有內點,請參見紅色和綠色圓圈(完成後通過迭代邊緣中心的x座標)
- 現在,內點(m,2n + 0.5)的垂直網格鄰居(m,2n)和(m,2n + 1)是內點,如果它們不在邊界上,請參閱scetch中的綠色點。
下面是一些僞代碼(C++ /蟒啓發:-)):
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)
聽起來很像[凸包](http://en.wikipedia.org/wiki/Convex_hull)。 – Dukeling
這些區域是否總是很簡單,或者它們是否可以像字母O那樣有洞? –
1.你想找到有界數字的區域或其內的點數? 2.什麼意思是該地區關閉?這是否意味着它的形狀要麼與座標線平行,要麼形成45度。與他們的角度? –