0

任意の数のパーリン ノイズ マップとそれぞれの重みを取得しました。すべての重みの合計は 1 ですが、違いはありません。

重みに関して最高値でそのノイズを取得したい。

私の最初のアプローチは、各パーリン ノイズから数値を取得し、これらをパーセンテージに変換し (そのためのループアップ テーブルがあります)、重みを掛けて、最も高い値を選択することでした。しかし、このアプローチには大きな欠点があります。小さな重みを識別し、大きな重みを優先するため、分布が台無しになります。20% に 0.2 の重みが表示されるようにします。

これをマップ ジェネレーターでタイル タイプを選択するために使用したいと考えています。複数のパーリン ノイズを使用します。これは、多くの異なるタイル タイプを使用して互いに境界線を引きたいため、グラデーションを使用できないためです。

この欠陥を修正する方法、またはタイルベースのマップを生成する別の方法を知っている人はいますか?

編集:その間、私はほぼ受け入れられる解決策を見つけました:

final float[] values = new float[noises.length];
for (int i = 0; i < values.length; i++)
    values[i] = noises[i].get(x, y) * (1f + (weights[i] - 1f / noises.length));

int max = 0;
for (int i = 1; i < values.length; i++)
    if (values[i] > values[max])
        max = i;
return noises[max];

唯一の欠点は不正確であることです。重みが 0f の場合でも、約 6% の時間でノイズが返されます。

4

2 に答える 2

1

おそらく、解決策は次のようになります。

Perlin pickOne(Perlin[] noise, double[] weights) {
   double sum = 0;
   for(double weight : weights) sum += weight;
   double choice = Math.random() * sum;
   for(int i = 0; i < weights.length; ++i) {
      choice -= weights[i];
      if(choice <= 0) {
         return noise[i];
      }
   }
   throw new IllegalArgumentException("Must have at least one weight!");
}

(つまり、マップ値ではなく、重みに完全に基づいてノイズマップの1つを選択します。ここでそれを選択するために行っていることは、すべての重みを数直線上に端から端まで配置することとして想像できます。 、それらの中の値を選び、それがどの重みに含まれるかを把握します。)

于 2013-03-21T18:40:39.567 に答える
0

「私の最初のアプローチは、各パーリン ノイズから数値を取得し、これらをパーセンテージに変換し (そのためのループアップ テーブルがあります)、重みを掛けて、最も高い値を選択することでした。しかし、このアプローチには大きな欠点があります。 20% に 0.2 の重みが表示されるようにしたい."

私が提案するのは次のとおりです。

1) すべてのパーセンテージ*重みの合計を合計します

2) 0 から sum の間の乱数を選択します

3) ランダムな数値を超えるまで、パーセンテージ * 重量の項目を追加して列挙します - それを選択します

これにより、パーセンテージ * 重みで重み付けされたすべての可能性に対してランダムな分布が行われます。したがって、2、8、および 6 がある場合、2 は 2/16 の確率で表示され、8 8/16 の確率で表示され、 6 6/16 の時間。

于 2013-03-22T00:10:24.117 に答える