我有一个任意数量的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%内恢复。
答案 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的时间。