2016-12-08 6 views
0

私は"Midpoint displacement algorithm example"からコードを取り出し、それを少しきれいにして、それを1Dの線形テレインジェネレータとして動作させるために再試行しました。この中点変位アルゴリズムの「粗さ定数」とは何ですか?どのように修正できますか?

public boolean setMidpointDisplacement(int x1, int x2) { 
     // Exit recursion if points are next to eachother 
     if (x2 - x1 < 2) { 
      return false; 
     } 

     final int midX = (x1 + x2)/2; 
     final int dist = x2 - x1; 
     final int distHalf = dist/2; 

     final int y1 = map[x1]; 
     final int y2 = map[x2]; 
     final int delta = random.nextInt(dist) - distHalf; // +/- half the distance 
     final int sum = y1 + y2; 
     map[midX] = (sum + delta)/2; // Sets the midpoint 

     // Divide and repeat 
     setMidpointDisplacement(x1, midX); 
     setMidpointDisplacement(midX, x2); 

     return true; 

} 

コードがうまく動作しているようですし、実行可能な地形を生成

(あなたが基本的なGUIで、how I've tested itを見ることができる)、"Generating Random Fractal Terrain""Mid Point Displacement Algorithm"を読んだ後、私の質問:下記のdoMidpoint()方法の私の新しいバージョンがあります:

このコードで暗黙的に使用されている「粗さ定数」をどのように特定できますか?それから、どうすれば変更できますか?

さらに、これは私の主要な質問に直接関係するかもしれませんが、私はコードがy値の合計を "デルタ"(変化量)に加え、これを2で割ることに気付きました - これは合計を平均化し、デルタ/ 2を加算するのと同じですが。これは「粗さ定数」に何らかの影響を与えますか?私は

map[midX] = sum/2 + delta/K; 

を行うことができ、Kは今「粗定数」の代表だろうと考えていますが、これは正確であるかどうかは私には平滑化を制御できるように思えるので、私は、よく分かりません「ランダムフラクタル地形を生成する」で定義されているように、「ループを通過するたびに乱数範囲がどのくらい減少するか」を直接制御することはありません。

私が以前に言ったように、私が見つけた2D MDPノイズジェネレータを1Dバージョンに移植しました。しかし、私はそれを正確に行っていることを確信しています。

答えて

1

このコードで暗黙的に使用されている「粗さ定数」をどのように特定できますか?

citedでは、粗さは最大ランダム変位を減らす量です。あなたの変位は、あなたのdist = x2-x1random.nextInt(dist) = dist*random.nextDouble()であり、あなたがこのDISTの半分と他の1つの再帰ステップから行くように、(引用用語で)roughness == 1

そして、私はそれをどのように変えることができるということになりますか?

public boolean setMidpointDisplacement(int x1, int x2, int roughness) { 
    // Exit recursion if points are next to eachother 
    if (x2 - x1 < 2) { 
     return false; 
    } 

    // this is 2^-roughness as per cited 
    // you can pass it precalculated as a param, using it as such here 
    // is only to put it into a relation with the cited 
    double factor=1.0/(1<<roughness); 

    final int midX = (x1 + x2)/2; 
    final int dist = x2 - x1; 
    final int distHalf = dist/2; 

    final int y1 = map[x1]; 
    final int y2 = map[x2]; 
    // and you apply it here. A cast will be necessary though 
    final int delta = factor*(random.nextInt(dist) - distHalf); // +/- half the distance 

    final int sum = y1 + y2; 
    map[midX] = (sum + delta)/2; // Sets the midpoint 

    // Divide and repeat 
    setMidpointDisplacement(x1, midX, roughness); 
    setMidpointDisplacement(midX, x2, roughness); 

    return true; 

} 
さらに

、これは直接私の主要な質問に関連してもしなくてもよいが、私はコードが「デルタ」へのyの値の合計を加えることに気付きました(変化これを2で割ります。

その方法は、1つの部門で行う利点があります。 intで作業するとき、累積切り捨てエラーは1つのdivで小さくなります(少し速くはないでしょう)。

+0

偉大な答え。しかしこの時点では、 'delta'に(0,1)の二倍の範囲を掛けるだけではないのですか?私は' factor 'を1/2、1/4、1/8など –

+0

@KartikChughヅ「デルタに(0,1)の二倍の範囲を掛け合わせるだけの違いがあれば?」と言いました。 '(用語では)カーブ/サーフェスの**滑らかさ**が実際に増加し、私はその用語を誤った名前と呼ぶだろう。私は1に近い乗算係数の高い値を想像しています(そしてなぜ1に制限するのか?)、かなりギザギザの地形になります。 –

関連する問題