【问题标题】:Map Generator with Weighted Perlin Noises带有加权柏林噪声的地图生成器
【发布时间】:2013-03-21 18:22:29
【问题描述】:

我有任意数量的柏林噪声图和每个的权重。所有权重的总和为 1,但这不应该有所作为。

我想获得关于权重的最高值的噪声。

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

我想将它用于地图生成器以选择图块类型。我使用多个 perlin 噪声,因为我想使用许多不同的瓷砖类型来彼此相邻,因此不能使用渐变。

有谁知道如何修复这个缺陷,或者用不同的方法来生成基于图块的地图?

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

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% 的所有时间内返回。

【问题讨论】:

  • 您所说的“重量的最高值”到底是什么意思?当我第一次阅读时,我假设您想要区分小权重噪声图。
  • 类似于 perlin 值 * 重量,然后选择最大的。但我也希望每一个都选择等于权重,例如权重为 0.2 的噪声应在 20% 的时间中最高。

标签: java random perlin-noise stochastic


【解决方案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!");
}

(也就是说,完全根据权重,而不是地图值来选择噪声图之一。我在这里选择它所做的工作可以想象为将所有权重端到端布置在一个数轴,在其中选择一个值,然后找出它属于哪个权重。)

【讨论】:

  • 嗯,因为这忽略了地图值,所以生成的地图看起来非常随机和分散。
【解决方案2】:

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

我的建议是:

1) 将所有百分比*权重相加

2) 选择一个介于 0 和 sum 之间的随机数

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

这将对所有按百分比*权重加权的可能性进行随机分布,因此如果您有 2、8 和 6,则 2 出现 2/16 的时间,8 8/16 的时间和 6 6/16 的时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-11
    • 1970-01-01
    • 2021-04-29
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    • 2014-12-24
    相关资源
    最近更新 更多