【发布时间】:2013-10-04 02:02:50
【问题描述】:
所以在过去的几天里,我一直在制作一个用 java 编写的程序生成程序,但是每当我进行输出时,它就会出现像纸一样的水洗纹理。我不明白为什么会这样做,虽然它很酷,但我想知道是否有人可以向我解释我的程序是如何得出这个结果的。
来源:http://pastebin.com/frCh03VW
我原以为这种逻辑会创建一个更像云的高度图,但它却给了我这个:
【问题讨论】:
标签: java random 3d procedural
所以在过去的几天里,我一直在制作一个用 java 编写的程序生成程序,但是每当我进行输出时,它就会出现像纸一样的水洗纹理。我不明白为什么会这样做,虽然它很酷,但我想知道是否有人可以向我解释我的程序是如何得出这个结果的。
来源:http://pastebin.com/frCh03VW
我原以为这种逻辑会创建一个更像云的高度图,但它却给了我这个:
【问题讨论】:
标签: java random 3d procedural
您正在使用java.util.Random 生成纹理。当然,计算机中没有什么是真正随机的。标准 Java 库使用经典的 linear congruential pseudorandom number generator,它对于大多数用途来说速度很快且很好,但对于严肃的东西仍然被认为是弱的。我所说的“弱”是指它可以被预测并在密集使用时表现出“非随机性”。这可能是您在此处看到的模式的来源。
另一个可能的问题来源是您首先生成一个随机种子数组。但是如果你看Random.next()在java.util中的实现:
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int)(nextseed >>> (48 - bits));
}
您看到 Random 的过程是生成一个新种子并根据对该种子的简单计算返回一个值。我没有数学背景来确定这一点,但也许这种技术会产生一个种子列表,当你之后使用它们时会产生类似的伪随机序列,因为它们以某种方式相互依赖,已经由同一个随机生成器生成,并且还会生成模式。
您可以尝试什么:使用更好的伪随机生成器。您可以使用java.security.SecureRandom,它具有“加密强度”,因此它应该足以满足您的使用需求。不幸的是,它没有java.util.Random 快。但你至少可以试一试,看看你是否找到相同的模式。如果不是,那么随机生成器是坏的;如果您仍然找到模式,那么很可能它来自您的算法。
如果我说伪随机发生器不够随机,如果SecureRandom对你来说太慢了,你可以在网上找到一个“Mersenne Twister”算法的实现,它更快更好比线性同余法。
【讨论】:
尼古拉斯,
如果这不正确,我提前道歉,但是查看您的代码并自己编译我发现该模式在很大程度上取决于 mshift 变量。如果您将其设置为一个相对较大的数字(出于我的目的,我将其设置为 1000),您会发现更多的静态和白噪声。相反,如果您将其设置得相对较低(出于我的目的,我将其设置为 10),您将得到您给出的海浪状或水洗纸描述。
我会假设,无需太多测试,创建的图像与您在相应 y 之前遍历每个 x 值这一事实有很大关系。
我没有更多时间为此做出贡献,因为我有自己的项目将于今天晚上 11:59 到期,但也许我不久前做的一个项目可能会对您有所帮助。我做了一个粘贴,以防你发现它有好处:
【讨论】: