2010-06-25 60 views
11

我需要將瓷磚放置在從中心點輻射的大網格上,看起來有機和隨機。新的瓷磚需要在網格上找到一個至少與另一個瓷磚接觸的開放空間。隨機平鋪佈局

任何人都可以指向我的方向任何可能有助於此?或者我可以讀懂的一些基本概念就是這個意思嗎?

例如,在此圖片中,已經創建了一個形狀(黃色),我可能正在接收一個新的圖塊,可能是1x1,2x2或3x3。試圖找到一個很好的方法來找出我可以放置新瓷磚的位置,以便它將觸及最大量的當前瓷磚。

圖片: alt text http://osomer.com/grid.JPG

+0

這些瓷磚是否都是相同的,你想要他們創造的形狀是有機的和隨機的,還是你有一堆瓷磚可以加入,並希望生成的正方形看起來有機和隨機? – 2010-06-25 05:04:12

+0

你能提供任何圖像或草圖來說明你的意思嗎?目前尚不清楚你所考慮的網格是笛卡爾還是極地。或者它應該是有機的和隨機的。您是否嘗試過以您描述的方式放置瓷磚,以及這樣做是如何失敗的? – brainjam 2010-06-25 05:07:22

+0

添加了圖片和更多說明。我的瓷磚通常是一個方形的圖像,但未來可能是2x2或3x3或更多。 – 2010-06-25 05:11:56

回答

3

或者,你可以爲黃瓦「侵蝕」走在藍/後臺解決這個問題。要做到這一點,在每個步驟中,都要有一個黃色的方塊,將一個固定的號碼添加到所有與其相鄰的所有背景圖塊的「侵蝕總和」中,並以基本方向排列(也許可能只是背景圖塊相鄰的一部分背景圖塊的一部分)它對角地)。然後,當需要放置新瓷磚時,您可以爲每個背景瓷磚選取一個從0到的隨機數E;然後,最大的一個被「侵蝕」掉了。或者,你可以做一個簡單的加權隨機選擇,E是他們的權重。

對於2x2或3x3拼貼,您只能從適合「貼合」2x2或3x3正方形的拼貼中拾取(也就是說,2x2或3x3的邊緣被蝕刻的拼貼,以致它不會導致與已放置的圖塊重疊)。但是,真的,你永遠不會得到像逐個侵蝕/瓷磚放置那樣自然的東西。

只有當你添加一個新的瓷磚,增加它的腐蝕總和時(簡單的+=),你可以節省時間重新計算腐蝕和。在這一點上,它與提出的另一個答案基本相同,儘管具有不同的觀點/哲學。

糜爛的樣品網格總結é,直接基數鄰居是+4,和對角線鄰居是+1:

Erosion Sums http://img199.imageshack.us/img199/4766/erosion.png

具有較高Ë的那些最有可能被「侵蝕」掉;例如在這一個中,西面和南面的兩個小入口最有可能被黃色侵蝕掉,其次是北面和東面的較小海灣。最不可能接觸到一個角落的黃色。您可以通過爲每個圖塊分配0到E的隨機數並侵蝕具有最高隨機數的隨機數,或者執行簡單的加權隨機選擇,或通過您選擇的任何決策方法來決定哪一個。

+0

好的解決方案,雖然這句話:「從0到E選擇一個隨機數字;最大的一個是」被侵蝕掉「 「似乎沒有任何意義。 'E'值不需要是唯一的,或者是連續的,所以我不知道這個選擇方法是如何工作的。 – 2010-06-25 09:44:55

+0

@Nick - 從前面的子句:*對於每個背景圖塊* - 也就是說,如果您有四個E值爲[1,5,3,2]'的tile,並且'rand()'是一個函數返回一個從0到1的隨機均勻分佈的有理數,你會發現'[rand()* 1,rand()* 5,rand()* 3,rand()* 2]',那些。 – 2010-06-25 09:56:07

+0

啊。這基本上是你繼續描述的加權隨機選擇,但是隻有每個選擇需要更多的隨機數。 – 2010-06-25 10:07:59

2

對於純粹隨機的,你開始與一個空的網格和「候選人」名單(也爲空)。

將第一個圖塊放置在網格中心,然後將每個相鄰圖塊添加到剛剛放置到「候選」列表中的圖塊。然後,每轉一圈,在「候選人」列表中選擇一個隨機條目,並在那裏放置一個拼貼。查看剛剛放置圖塊的位置旁邊的每個相鄰網格位置,並且對於每個也爲空的網格位置,將其放在下一次「候選」列表中(如果尚未存在)。

爲了避免在您的瓷磚網格中創建孔,請根據已經填充的相鄰瓷磚的數量增加選擇網格位置的可能性(如果只有一個相鄰瓷磚已填充,則其可能性很低。 '全部填滿了,它將有很高的可能性)。

在僞代碼:

grid = new array[width,height]; 
candidates = new list(); 

function place_tile(x,y) { 
    // place the tile at the given location 
    grid[x,y] = 1; 

    // loop through all the adjacent grid locations around the one 
    // we just placed 
    for(y1 = y - 1; y1 < y + 1; y1++) { 
     for(x1 = x - 1; x1 < x + 1; x1++) { 
      // if this location doesn't have a tile and isn't already in 
      // the candidate list, add it 
      if (grid[x,y] != 1 && !candidates.contains(x1,y1)) { 
       candidates.add(x1,y1); 
      } 
     } 
    } 
} 

// place the first tile in the centre 
place_tile(width/2, height/2); 

while (!finished) { 
    // choose a random tile from the candidate list 
    int index = rand(0, candidates.length - 1); 

    // place a tile at that location (remove the entry from 
    // the candidate list) 
    x, y = candidates[index]; 
    candidates.remove(index); 
    place_tile(x, y); 
} 
+0

哇,這看起來不錯。我要給這個破解,看看我能否得到它的工作。邏輯聽起來很合理。 – 2010-06-25 05:14:53

+0

在我看到您對2x2和3x3拼貼的編輯之前,我寫了這篇文章,但我相信這可以重新考慮,以考慮到這一點。您可能需要稍微擴展「候選人」結構以考慮瓷磚的其他尺寸... – 2010-06-25 05:18:31

1

問題與你的問題是'有機和隨機'可以是許多不同的事情。 讓我給兩個環節

  • 產生random fractal terrain(看部分的「陰天」,並想象一下,你把它交給B/W,或在您的案件黃/背景)。
  • 模擬erosion(看圖片下「侵蝕」)

上述兩個樣本是「有機和隨機」給我,但你可能並不滿足這些。所以,我認爲你將不得不更好地定義什麼是「有機的和隨機的」。

現在,我要你的指導規則的定義,添加新的地磚(但不認爲這必然是同樣的問題),我理解爲:

鑑於兩個形狀(假設位圖) 找到 形狀,例如的相對位置即 接觸的邊數是最大

我也將假定

  • 重疊不允許
  • 可以保留所得內孔,合併形狀
  • 可以旋轉形狀

在這種條件下需要測試少,則x ÿ溶液和在每次需要 - 丟棄它,如果存在重疊 - 丟棄它,如果他們不碰 - 如果他們觸碰再算上邊緣是常見的數 所有這三個以上的測試可以在恆定的時間b做y掃描所有的黃色瓷磚(數量是konst x * y)

所以,上述可以很容易地在O(n^4)中完成,這對你來說足夠好嗎?

0

計算雙圖的隨機生成樹,即頂點爲單元中心的網格。爲此,從網格中心開始,隨機進行深度優先搜索。然後繪製細胞以增加距離中心的樹木距離。