這是一個簡單算法的僞代碼,該算法將在增加半徑的球形外殼中搜索,直到找到一個點或它用完陣列。讓我們假設condition
返回true或false,並先後獲得了X,Y,Z座標進行測試和陣列本身,出界外返回false(而不是爆炸)座標:
def find_from_center(center, max_radius, condition) returns a point
let radius = 0
while radius < max_radius,
let point = find_in_spherical_husk(center, radius, condition)
if (point != null) return point
radius ++
return null
難度部分在find_in_spherical_husk
之內。我們有興趣檢查出這樣的點
dist(center, p) >= radius AND dist(center, p) < radius+1
這將是我們的穀殼操作定義。我們可以在O(n^3)中遍歷整個3D數組尋找這些數據,但是這在時間上會非常昂貴。更好的僞代碼如下:
def find_in_spherical_husk(center, radius, condition)
let z = center.z - radius // current slice height
let r = 0 // current circle radius; maxes at equator, then decreases
while z <= center + radius,
let z_center = (z, center.x, point.y)
let point = find_in_z_circle(z_center, r)
if (point != null) return point
// prepare for next z-sliced cirle
z ++
r = sqrt(radius*radius - (z-center.z)*(z-center.z))
這裏的想法是給每個殼切成沿Z軸(任意軸都可以)圈,然後看看每個切片分別。如果你在看地球,而兩極是z軸,那麼你會從北向南切片。最後,您將執行find_in_z_circle(z_center, r, condition)
來查看每個圓圈的圓周。您可以使用Bresenham circle-drawing algorithm來避免一些數學問題;但我認爲與檢查condition
相比,節省的費用可以忽略不計。
您正在混合任務和解決方案。而你固定的解決方案的部分不適合這個問題。誰曾經說過,通過一個細胞步驟你會發現最接近的「好」細胞?相反,下一個距離層的單元將大部分分離。 – Gangnus
@fafl:我看了一下R-tres,但是我沒有看到它是如何用來爲給定的'p'找到最接近的'q'的。AFAIU,在R-tree中搜索決定某個分支,然後將找到該分支內的最近點,如果您決定選擇錯誤的分支,則不一定是所有分支內的最近點。 – siracusa