我一直在研究perlin脚本,但在创建简单的伪随机值方面遇到了问题。
我需要能够从xy坐标创建种子值,但x + y对重复出现的值有明显的问题。它们也会进入负空间,因此x ^ y不起作用。
很抱歉,如果已经在其他地方已经回答了这个问题,但是我不理解或找不到它。
答案 0 :(得分:1)
你想为每个x,y对分配一个可重复的随机数吗?
使用x,y作为种子的线性或一般函数组合将在分布中给出工件(至少如果不使用非常复杂的函数)。 试试这个,我有同样的问题,它对我有用
//seeded random for JS - integer
function irnd2()
{
a=1664525;
c=1013904223;
m=4294967296;
rnd2.r=(rnd2.r*a+c)%m;
return rnd2.r;
}
//seeded random for JS - double [0,1]
function rnd2()
{
a=1664525;
c=1013904223;
m=4294967296;
rnd2.r=(rnd2.r*a+c)%m;
return rnd2.r/m;
}
rnd2.r=192837463;
//seed function
function seed2(s)
{
s=s>0?s:-s;
rnd2.r=192837463^s;
}
//my smart seed from 2 integer
function myseed(x,y)
{
seed2(x);//x is integer
var sx=irnd2();//sx is integer
seed2(y);//y is integer
var sy=irnd2();//sy is integer
seed2(sx^sy);//using binary xor you won't lose information
}
为了使用它:
myseed(x,y);
irnd2();
通过这种方式,您可以获得良好的不相关随机序列。
我在JS中使用它,但它也应该在其他语言中使用,假设seed的参数和rnd的返回值是一个整数。
答案 1 :(得分:0)
首先取x
和y
的绝对值;然后x^y
将正常工作。创建伪随机源的最简单方法之一是随着时间的推移。您可以尝试将x^y
乘以当前系统时间;这种方法产生重复种子值的可能性极低。
答案 2 :(得分:0)
如果你知道你所拥有的值的范围,你可以简单地将x和y作为用零填充的字符串,附加两个字符串,然后通过哈希函数运行结果字符串。
答案 3 :(得分:0)
在C#中,改进并改进了alexrh的回答。只需设置Random.seed = MyUtils.GetSeedXY(x, y)
,就可以了。
public static class MyUtils
{
static int seed2(int _s)
{
var s = 192837463 ^ System.Math.Abs(_s);
var a = 1664525;
var c = 1013904223;
var m = 4294967296;
return (int) ((s * a + c) % m);
}
public static int GetSeedXY(int x, int y)
{
int sx = seed2(x * 1947);
int sy = seed2(y * 2904);
return seed2(sx ^ sy);
}
}
答案 4 :(得分:-1)
您需要更好地定义问题以获得最佳答案。
如果您的x和y值相对较小,您可以将它们放入整数的高低部分(您的语言中的种子是整数),例如对于32位平台:
int seed = x<< 16 + y;
如果不允许种子值为负数(我不完全理解你的问题中“负空间”的含义,无论你是指地理位置还是种子价值),你都可以取绝对值种子。
如果你的意思是坐标可以有负值,那么你最好的行动方案取决于你是否想要一个坐标的相同种子,反之亦然。