如何平滑我的地形发生器?

时间:2014-04-03 23:41:08

标签: java algorithm random noise terrain

我正在尝试一种新的随机景观生成算法。这种方法是我的想法,所以它可能变得不可能。与此同时,我正试图解决这个问题。

    public static void generate(){
    for(int x = -64; x <= 64; x++){
        for(int y = -64; y <= 64; y++){
            double val = 2d;
            for(int i = x - 4; i <= x + 4; i++){
                for(int j = y - 4; j <= y + 4; j++){
                    double w = Math.pow(hypotenuse(x, y, i, j), 1);
                    val += (1 * (random(i, j) / w));
                }
            }
            tileSet(x, y, val);
        }
    }
}

在我解释这段代码之前,让我说这是一款2D游戏,因此高度图是瓷砖的类型而不是实际高度。水最低(0),然后是沙子,草和树(3)。为了测试,我在两个维度中从-64循环到64。对于每个图块,声明一个值(以2或草开头)。然后我们围绕这个图块循环(-4到4是任意数量,我有通过修改此值可以在结果中实现显着差异,但4似乎没问题)。现在,变量w代表重量。每个(i,j)点离(x,y)越远,随机值在加到val之前给出的权重越小。我已经尝试了w的不同指数,下一行的不同乘数(在这个例子中两个情况都是1);较低的指数和乘数似乎扩大了最终结果而不必平滑,较高的指数则相反,你会得到更多的树木更接近水,中间的草和沙子更少。

这是方法random()

public static double random(int x, int y){
    Random random = new Random(seed * 17717171L + x * 22222223L + y * 111181111L);
    return random.nextGaussian() / 2d;
}

在这些内部循环完成后,设置x,y的值。

这是一次运行

too much roughness

这是.5的乘数,意思是val += (.5 * (random(i, j) / w));

still too much roughness

正如你所看到的,有更多的沙子和草地,明显更少的树木(和整体水),但仍然有很多小的颠簸。因此,它无法有效地改变规模。

感谢您的时间!

1 个答案:

答案 0 :(得分:1)

您正在做的事情被称为inverse distance weighting。正如文章所指出的,关键参数是权重的指数。所以在你的代码中,试试

double w = Math.pow(hypotenuse(x, y, i, j), p);

p视为0.25, 0.5, 1.0, 2.0,等。

您的算法的一个细微变体可能会使算法的推理更容易:不是为每个单元格生成随机值并添加到相邻单元格,而是从每个单元格角处生成随机值开始,然后使用从细胞中心测量的反距离加权来计算细胞值。

使用这种方案,有助于单元格值的随机值都以统一的方式处理,而不是一个随机值得到加权1而其他值得到反距离加权。

如果您还没有遇到过gradient noise,您可能也会感兴趣。