带加权Perlin噪声的地图生成器

时间:2013-03-21 18:22:29

标签: java random perlin-noise stochastic

我有一个任意数量的perlin噪声图和每个的权重。所有权重之和为1,但这并没有什么区别。

我希望得到有关重量的最高值的噪音。

我的第一种方法是从每个perlin噪声中获取数字,将它们转换为百分比(我有一个循环表),乘以权重并选择最高值。但是这种方法存在一个巨大的缺陷:它可以区分较小的权重并且有利于较大的权重,因此会影响分布。我想要一个0.2的重量出现在20%。

我想将它用于地图生成器以选择平铺类型。我使用多个perlin噪声,因为我想使用许多不同的tile类型相互连接,因此不能使用渐变。

有谁知道如何解决这个漏洞,或者以不同的方式生成基于图块的地图?

编辑: 与此同时,我找到了一个几乎可以接受的解决方案:

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%内恢复。

2 个答案:

答案 0 :(得分: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 :(得分:0)

“我的第一个方法是从每个perlin噪声中获取数字,将它们转换为百分比(我有一个循环表),乘以权重并选择最高值。但这种方法有一个巨大的缺陷:它区分较小的权重并且偏向较大的权重,因此会影响分布。我希望权重为0.2,以20%的比例出现。“

我建议的是:

1)加上所有百分比*权重

的总和

2)选择0到和之间的随机数

3)枚举添加百分比*重量项,直到你超过你的随机数 - 选择

这会对按百分比*权重加权的所有可能性进行随机分布,所以如果你有一个2,一个8和一个6,则2出现2/16的时间,8 8/16的时间和6 6/16的时间。