2013-07-23 25 views
4

我正在嘗試實現一個地牢生成算法(presented heredemo-ed here),該算法涉及生成相互重疊的隨機數量的單元格。然後將細胞推開/分開然後連接。現在,原始的海報/作者描述了他正在使用分離導向算法來將細胞均勻分佈在一個區域上。我沒有太多的植絨算法和/或分離轉向行爲的經驗,因此我轉向谷歌的解釋(並發現this)。我的實現(基於上次文章提到的)如下:Lua分離轉向算法將重疊房間分組到一個角落

function pdg:_computeSeparation(_agent) 
    local neighbours = 0 
    local rtWidth = #self._rooms 
    local v = 
    { 
    x = self._rooms[_agent].startX, 
    y = self._rooms[_agent].startY, 
    --velocity = 1, 
    } 

    for i = 1, rtWidth do 
    if _agent ~= i then 
     local distance = math.dist(self._rooms[_agent].startX, 
           self._rooms[_agent].startY, 
           self._rooms[i].startX, 
           self._rooms[i].startY) 
     if distance < 12 then 
     --print("Separating agent: ".._agent.." from agent: "..i.."") 
     v.x = (v.x + self._rooms[_agent].startX - self._rooms[i].startX) * distance 
     v.y = (v.y + self._rooms[_agent].startY - self._rooms[i].startY) * distance 
     neighbours = neighbours + 1 
     end 
    end 
    end 


    if neighbours == 0 then 
    return v 
    else 
    v.x = v.x/neighbours 
    v.y = v.y/neighbours 
    v.x = v.x * -1 
    v.y = v.y * -1 
    pdg:_normalize(v, 1) 
    return v 
    end 
end 

self._rooms是包含原始X和電網間的Y位置,與它一起表格的寬度和高度(endX ,endY)。

的問題是,代替tiddly佈置細胞在網格上,它需要的重疊細胞,並將它們移動到從1,1進入的區域爲距離+ 2,距離+ 2(as seen in my video [youtube]

我想了解爲什麼會發生這種情況。

如果它的必要,在這裏我分析的網格表,獨立和分離後填充單元格:

function pdg:separate() 
    if #self._rooms > 0 then 
    --print("NR ROOMS: "..#self._rooms.."") 

    -- reset the map to empty 
    for x = 1, self._pdgMapWidth do 
    for y = 1, self._pdgMapHeight do 
     self._pdgMap[x][y] = 4 
    end 
    end 

    -- now, we separate the rooms 
    local numRooms = #self._rooms 
    for i = 1, numRooms do 
    local v = pdg:_computeSeparation(i) 
    --we adjust the x and y positions of the items in the room table 
    self._rooms[i].startX = v.x 
    self._rooms[i].startY = v.y 
    --self._rooms[i].endX = v.x + self._rooms[i].endX 
    --self._rooms[i].endY = v.y + self._rooms[i].endY 
    end 


    -- we render them again 
    for i = 1, numRooms do 
    local px = math.abs(math.floor(self._rooms[i].startX)) 
    local py = math.abs(math.floor(self._rooms[i].startY)) 

    for k = self.rectMinWidth, self._rooms[i].endX do 
     for v = self.rectMinHeight, self._rooms[i].endY do 
     print("PX IS AT: "..px.." and k is: "..k.." and their sum is: "..px+k.."") 
     print("PY IS AT: "..py.." and v is: "..v.." and their sum is: "..py+v.."") 
     if k == self.rectMinWidth or 
      v == self.rectMinHeight or 
      k == self._rooms[i].endX or 
      v == self._rooms[i].endY then 
      self._pdgMap[px+k][py+v] = 1 
     else 
      self._pdgMap[px+k][py+v] = 2 
     end 
     end 
    end 
    end 
end 

回答

1

我已經實現這個生成算法爲好,我碰到或多或少相同問題。我所有的長方形都落在了角落裏。

我的問題是,我是歸一化的速度矢量具有零長度。如果你將這些歸一化,你除以零,導致NaN。

你可以通過你的速度的長度是否爲零,任何進一步的計算中使用它之前,簡單地執行檢查解決這個問題。

我希望這有助於!

0

嗯,我知道這是一個老問題,但我注意到的東西,也許它可以給別人有用的,所以......

我認爲這裏有一個問題:你爲什麼

v.x = (v.x + self._rooms[_agent].startX - self._rooms[i].startX) * distance 
v.y = (v.y + self._rooms[_agent].startY - self._rooms[i].startY) * distance 

將這些方程乘以距離? 「(self._rooms[_agent].startX - self._rooms[i].startX)」已包含(平方)距離! 另外,將所有內容乘以「distance」即可修改以前存儲在v中的結果! 如果你至少把「v.x」放在方括號外,結果會更高,normalize函數會修正它。雖然這是一些無用的計算...

順便說我敢肯定的代碼應該是這樣的:

v.x = v.x + (self._rooms[_agent].startX - self._rooms[i].startX) 
v.y = v.y + (self._rooms[_agent].startY - self._rooms[i].startY) 

我做出了榜樣。假設你有(0,0)的主代理和(0,-2),( - 2,0)和(0,2)中的三個鄰居。分離轉向行爲會使主劑沿標準化方向(1,0)向X軸移動。 我們只關注結果向量的Y分量。

數學應該是這樣的:

--Iteration 1 
v.y = 0 + (0 + 2) 
--Iteration 2 
v.y = 2 + (0 - 0) 
--Iteration 3 
v.y = 2 + (0 - 2) 
--Result 
v.y = 0 

這與我們的理論是一致的。 這是你的代碼做什麼:

(note that the distance is always 2) 
--Iteration 1 
v.y = (0 + 0 + 2) * 2 
--Iteration 2 
v.y = (4 + 0 - 0) * 2 
--Iteration 3 
v.y = (8 + 0 - 2) * 2 
--Result 
v.y = 12 

如果我得到了分離轉向行爲的權利,這不可能是正確的。