2016-07-06 105 views
2

我试图找出办法有用于固定的规模:钻石广场算法固定大小

https://en.wikipedia.org/wiki/Diamond-square_algorithm

我看到算法要求的2(+1)大小的力量阵列。

我遇到的问题是,我想有不管决议产生相同的高度图。所以如果我有一个512的分辨率,它看起来与分辨率256相同,但是只有更少的细节。我只是无法弄清楚如何做到这一点。

我的初始想法是总是创建在某一尺寸如高度图1024和下采样到我想要的水库。问题是我希望较高的分辨率相当高(比如说4096),并且这会严重降低较低分辨率下的性能,因为我们必须以最高分辨率运行算法。

目前该算法是在JavaScript这里是一个片段:

function Advanced() { 
    var adv = {}, 
    res, max, heightmap, roughness; 

    adv.heightmap = function() { 
     // heightmap has one extra pixel this is ot remove it. 
     var hm = create2DArray(res-1, res-1); 
     for(var x = 0;x< res-1;x++) { 
      for(var y = 0;y< res-1;y++) { 
       hm[x][y] = heightmap[x][y]; 
      } 
     } 
     return hm; 
    } 

    adv.get = function(x,y) { 
     if (x < 0 || x > max || y < 0 || y > max) return -1; 
     return heightmap[x][y]; 
    } 

    adv.set = function(x,y,val) { 
     if(val < 0) { 
      val = 0; 
     } 

     heightmap[x][y] = val; 

    } 

    adv.divide = function(size) { 
     var x, y, half = size/2; 
     var scale = roughness * size; 
     if (half < 1) return; 

     for (y = half; y < max; y += size) { 
      for (x = half; x < max; x += size) { 
       adv.square(x, y, half, Math.random() * scale * 2 - scale); 
      } 
     } 
     for (y = 0; y <= max; y += half) { 
      for (x = (y + half) % size; x <= max; x += size) { 
       adv.diamond(x, y, half, Math.random() * scale * 2 - scale); 
      } 
     } 
     adv.divide(size/2); 
    } 

    adv.average = function(values) { 
     var valid = values.filter(function(val) { 
      return val !== -1; 
     }); 
     var total = valid.reduce(function(sum, val) { 
      return sum + val; 
     }, 0); 
     return total/valid.length; 
    } 

    adv.square = function(x, y, size, offset) { 
     var ave = adv.average([ 
      adv.get(x - size, y - size), // upper left 
      adv.get(x + size, y - size), // upper right 
      adv.get(x + size, y + size), // lower right 
      adv.get(x - size, y + size) // lower left 
     ]); 
     adv.set(x, y, ave + offset); 
    } 

    adv.diamond = function(x, y, size, offset) { 

     var ave = adv.average([ 
      adv.get(x, y - size), // top 
      adv.get(x + size, y), // right 
      adv.get(x, y + size), // bottom 
      adv.get(x - size, y) // left 
     ]); 

     adv.set(x, y, Math.abs(ave + offset)); 
    } 

    adv.generate = function(properties, resolution) { 
     Math.seedrandom(properties.seed); 

     res = resolution + 1; 
     max = res - 1; 
     heightmap = create2DArray(res, res); 

     roughness = properties.roughness; 

     adv.set(0, 0, max); 
     adv.set(max, 0, max/2); 
     adv.set(max, max, 0); 
     adv.set(0, max, max/2); 

     adv.divide(max); 
    } 

    function create2DArray(d1, d2) { 
     var x = new Array(d1), 
     i = 0, 
     j = 0; 

     for (i = 0; i < d1; i += 1) { 
      x[i] = new Array(d2); 
     } 

     for (i=0; i < d1; i += 1) { 
      for (j = 0; j < d2; j += 1) { 
       x[i][j] = 0; 
      } 
     } 

     return x; 
    } 

    return adv; 
} 

有谁这样做过?

+0

貌似没有再笑! – Dave3of5

回答

0

不太清楚,如果我理解你的问题还没有,但如果我可以,我会提供进一步的澄清。

你描述你想要在一个大小为512使用与256的分辨率的菱形方高度图而无需缩放了的情况下。我将通过一个使用2x2高度图的例子来说明4x4的“大小”。

钻石方高度图是真是一组顶点,而不是砖或正方形的,所以有大小2×2的高度图真如所示的一组3×3的顶点:

enter image description here

你可以要么使用拐角的高度来渲染它,要么通过取四个周围点的平均值,将它变成一个2×2的正方形集合 - 实际上,这只是没有位移步骤的算法的“平方”步骤。

enter image description here

因此,在这种情况下,左上方的 “高度” 是的平均值(0,0),(0,1),(1,1)和(1, 0)分。

如果你想在更高的分辨率得出这样的,你可能分裂每平方米成较小的一套4个格的基础上,它是每一个点的接近程度调整的平均水平。

enter image description here

所以现在左上角最方形的价值将是其周围的4个子点或相对于周围的点的位置的样本的样本。但实际上,这只是再次应用钻石平方算法而没有任何位移(无粗糙),因此您可以再次应用该算法并进行更大尺寸。

你说要去你不妨去将太多的处理器来处理,所以你可能想要去与较小尺寸此抽样方法的大小。一种有效的方法是将高度图渲染为纹理和样本以及所需的位置。

0

正确实施钻石&方算法具有相同的第一N步骤,无论地图分辨率,因此唯一需要确保相同的外观是使用了伪随机生成一些特定的种子。

为了使这项工作,你需要:

  1. 组种子
  2. 分配阵列,并设置基地随机性幅度
  3. 钻石
  4. 广场
  5. 基数较低的随机性幅度
  6. # 3直到最低分辨率命中

如果不是正确地降低随机性的大小,那么较低的递归/迭代层可以覆盖上层结果的形状,从而使其不起作用。

这里看到我这样做只是增加了种子:

看行:

r=(r*220)>>8; if (r<2) r=2; 

r是基础随机性幅度。你降低它的方式将决定结果的形状,因为你可以看到我没有将它除以2,而是乘以220/256,所以更低的分辨率有更大的颠簸,这符合我的需要。

现在,如果你想使用非2^x+1分辨率,然后选择更接近更大的分辨率,然后缩小,以使他们也为他们工作。缩小应仔细做,以保留它们的前几个递归/迭代步骤的主要网格点或使用双立方体...

如果你有兴趣看看更多最新的发电机基于连接的一种: