2012-01-06 147 views
0

我在Java中使用的ArrayList二維網格建,想給電網分割成更小網格的給定數。算法二維矩形網格分割成更小網格

我工作的任務是制定遊戲地圖在多個服務器上,這就是爲什麼我需要較小的地圖分成服務器分佈的模擬器。

我真的有兩個問題,第一個問題是給出一個X乘以Y的矩形(地圖)和一些部分將其拆分爲N,我怎樣才能將規則劃分成N個較小(但最好在面積上相等)矩形。

其次,我希望在如何實現2D的ArrayList而言上述方法的建議。

回答

1

如果n恰好是正方形,可以切成SQRT(n)的切片的每個方向上分割網格。否則,水平條紋將起作用(如果它不是一個問題,那些件在形狀上與整個地圖不相似)。如果保持形狀合理比保持大小相同更重要,可以考慮一種算法,從整個網格開始,並將最大的一塊分成兩半,直到獲得所需數量的塊。

當談到切割網格切片時,我假設你的意思是一個List<List<?>>,其中list.get(x).get(y)是(x,y)處的項目的2D ArrayList。然後,你可以只使用subList()在兩個方向:

List<List<?>> split(List<List<?>> in, int x1, int y1, int x2, int y2) { 
    List<List<?>> out = new ArrayList<List<?>>(w); 
    for(List<?> column : in.sublist(x1, x2)) { 
     out.add(column.subList(y1, y2)); 
    } 
    return out; 
} 

List<List<List<?>>> partitionEqualAspect(List<List<?>> grid, int n) { 
    int w = grid.size(); 
    int h = grid.get(0).size(); 
    int cols = (int)(sqrt(n) + .5); 

    // This many columns have (cols - 1) rows 
    int shortCols = Math.max(0, cols * cols - n); 
    // This many columns have (cols + 1) rows 
    int longCols = Math.max(0, n - cols * cols); 

    List<List<List<?>>> tiles = new ArrayList<List<List<?>>>(); 
    for(int c = 0; c < cols; ++c) { 
     int rows = cols + (c < shortCols ? -1 : c >= cols - longCols ? 1 : 0); 
     for(int r = 0; r < rows; ++r) { 
     tiles.add(split(grid, 
         w * c/cols, h * r/rows, 
         w * (c + 1)/cols, h * (r + 1)/rows)); 
     } 
    } 
    return tiles; 
} 

注意的是,這裏創建的網格片引用回到原來的電網和切片的變化將在滿格中反映出來。如果你想避免這種情況,你可以複製一切。

+0

感謝您的回覆。有沒有辦法將這兩種方法結合起來,以便它可以創建儘可能多的相同尺寸的正方形,然後將其餘部分分成水平(或豎直)條?關於切割網格的技巧非常完美,謝謝,我正在尋找..我肯定會使用副本,因爲這個問題更多地是關於初始化模擬器 - 後來每個網格都會根據服務器工作負載動態調整大小。 Thankyou,Dan – dlwells02 2012-01-06 18:52:48

+0

@Dan:這個怎麼樣:讓'cols =(int)(sqrt(n)+ .5)'。分成許多列。然後,如果'cols * cols> n',將第一個'n-cols * cols'分成'cols + 1'行,然後將其餘的行分成'cols'行。否則,將'cols * cols - n'分爲'cols - 1'行,其餘分爲'cols'行。例如,如果n = 28,cols = 5和3 * 6 + 2 * 5 = 28。如果n = 32,cols = 6和4 * 5 + 2 * 6 = 32. – 2012-01-06 19:26:08

+0

@Dan:請參閱上面的更改。 – 2012-01-06 20:04:00

2

回答第一個問題上分裂的X通過-Y矩形分成相等的面積N個較小的矩形...

我認爲最好的辦法是將其分割成N個子rects每個維持矩形主矩形的縱橫比相同。

N必須使得SQRT(N)產生一個積分的答案(例如N = 36SQRT(N)= 6)。因此,X-通過-Y被分解成SQRT(N) -by- SQRT(N)子rects。子矩形大小(XS,YS)的計算如下所示:

兩個X = X/SQRT(N)

伊蘇= Y/SQRT(N)

這種方法將總是給你Ñ只要sqrt(N)是一個整數值。根據N的值,你可能需要補償整數截斷誤差,方法是使一些子矩陣稍大一些,以完全覆蓋整個主矩形。

還有另一種方法是通過將主矩形的面積除以N來計算,然後將該結果的平方根提出M乘M的子平方,但這比粗糙的以上方法。

+0

我會試試這個,看起來很有用,謝謝! – dlwells02 2012-01-06 18:55:37