2016-07-06 6 views
2

私はのための固定スケールを持つ方法を把握しようとしています:ダイヤモンドスクエアアルゴリズムの固定サイズ

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

私はアルゴリズムがの2(1)サイズの電力を必要としていることがわかりアレイ。

私が抱えている問題は、解像度に関係なく同じ高さマップを作りたいということです。だから私は512の解像度を持っている場合、解像度256と同じように見えるでしょうが、詳細はあまりありません。私はちょうどこれを行う方法を理解することはできません。

私の最初の考えは、常にある次元で高さマップを作成することでした。 1024と私が望むressampleにダウン。問題は、高解像度を非常に高くしたい(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

あなたの質問をまだ理解しているかどうかはまだ分かりませんが、できる場合はさらに明確に説明します。

解像度256のダイヤモンド四角形の高さマップを拡大せずに512のサイズで使用する場合について説明しました。 2x2高さマップを使用して4x4の「サイズ」を使用する例を説明します。

ダイヤモンド平方ハイトが示すように2×2のサイズのハイトが本当に3x3の頂点の集合である、本当に頂点ではなく、タイルまたは正方形のセットです:

enter image description here

あなたは可能性がありコーナーの高さを使ってこれをレンダリングするか、4つの周囲点の平均をとって2x2の四角形に変換することができます。これは実際には変位ステップのないアルゴリズムの「正方形の」ステップです。

enter image description here

したがって、この場合には左上角の "高さ" は、(0,0)、(0,1)、(1,1)の平均値と(1あろう0)ポイント。

これをより高い解像度で描画したい場合は、各四角形を4つの小さな四角形に分割し、各点の近さに基づいて平均を調整することができます。

enter image description here

だから今左上最も正方形の値は約4サブ点またはその周囲の点に対する位置のサンプルのサンプルであろう。しかし、実際にはこれはダイアモンドスクエアアルゴリズムを変位(粗さなし)をかけずに再び適用したもので、アルゴリズムを再適用してより大きなサイズにすることもできます。

あなたが行きたいサイズに行くのは、プロセッサが処理するにはあまりにも大きすぎると言いました。したがって、このサンプリングアプローチをより小さなサイズにすることができます。効率的な方法は、高さマップをテクスチャとサンプルからレンダリングし、必要な位置をレンダリングすることです。

0

が正しく同じ外観を確保するための唯一のことは、擬似乱数発生器のためのいくつかの指定された種子を使用することであるので、&平方アルゴリズムは関係なく、マップの解像度の同じ第1 Nの工程を有するダイヤモンドを実施しました。

あなたが必要とするこの動作させるために:

  1. セットシード
  2. スクエア
  3. 下部ベースランダム性の大きさのダイヤモンド
  4. 配列とセットベースのランダム性の大きさ
  5. を割り当てる
  6. ループ#最小解像度がヒットするまで3

ランダム性の大きさを適切に下げないと、下位の再帰/反復レイヤーが上位レイヤーの結果の形を上書きして、これが機能しなくなる可能性があります。

は、ここで私はそれだけでシードを追加する方法を見て:

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

rは基本ランダム性の大きさである:

  • Diamond-square algorithm not working
    • はラインを参照してください。あなたがそれを下げる方法は、私が2で除算するのではなく、代わりに 220/256を掛けているのがわかるように、結果の形状を決定するでしょう。したがって、より低い解像度は、私の必要とするより大きなバンプを持っています。

      ここで、2^x+1の解像度以外の解像度を使用する場合は、より大きな解像度を選択してから縮小してください。最初のいくつかの再帰/反復ステップのメイングリッドポイントを保持するか、または2つのキューブを使用するためにスケーリングダウンを慎重に実行する必要があります...

      興味深い場合は、 1リンク:

    関連する問題