问题描述
所以我一直在开发一款利用程序地形和结构生成的游戏。现在,我正在处理结构生成——我使用了 Poisson-disc 采样,我计划在我的世界中实现块。但是,我的采样依赖于一颗种子。有没有办法接受 3 个或更多数字以输出与这些数字有某种关系的随机数?
另一方面,随机数不必在输入的可能范围内。
如果不可能,是否还有其他范式可以在无限程序生成的世界上实施泊松盘采样(或其替代方案)以创建结构?我有点卡住了。
示例:
Random x = new Random(138013,28282,37920)
x.nextInt() = 38309
Random y = new Random(138012,37920)
y.nextInt() = 28323
Random z = new Random(138013,37920)
z.nextInt() = 38309
//new Random(a,b,c).nextInt() does not have to be within ranges [a,b],[a,c],[b,c]
解决方法
您可以通过连接这三个值来创建种子:
new Random(138013,28282,37920) => new Random("138013" + "28282" + "37920")
这不是有效的代码,但我希望你明白原理。然后应该将字符串转换为long。如果数字太大太久,也许您可以应用ceratain modulo。喜欢 138013 % 10000
并对每个值都这样做。或者您可以将这三个值相加。
使用某些值的加密散列通常会导致结果的确定性降低。在您的情况下,例如:
public Random fromCoords(long x,long y,long z) throws Exception {
var buf = ByteBuffer.allocate(4 * 8);
buf.putLong(world_seed);
buf.putLong(x);
buf.putLong(y);
buf.putLong(z);
buf.flip();
var md = MessageDigest.getInstance("SHA-256");
md.update(buf);
var seed = ByteBuffer.wrap(md.digest()).getLong();
return new Random(seed);
}
可能足够了,但不是特别有效。如果这是一个问题,您可以使用一些小技巧代替 ByteBuffer
来避免大多数不必要的堆分配。