我使用libnoise生成2D精灵forrests。
然后我让我的世界更大,我目前在世界范围内工作1.0到-1.0。现在的问题是我不能再生成树被偏移的几个像素(从它们的网格位置)。所以他们不是全部排成一排。我曾经采用噪音值,当我放置一棵树时,我会将噪音值乘以一个int以使其更大并将其模数化以获得随机偏差,该偏差在世界上的每一点都是相同的。 / p>
// offset each forest decal by a small amount for asthetic purposes
surface_xy.x = surface_x + float(FOREST::HALF_UNIT - int(perlin_noise_value * 100.0) % FOREST::UNIT);
surface_xy.y = surface_y + float(FOREST::HALF_UNIT - int(perlin_noise_value * 200.0) % FOREST::UNIT);
现在,我的世界变得越来越大,我的公式必须在世界任何地方都可以工作,因为噪音值非常小,所以不起作用。如何从1.1055228575200001e-012获得例如-5和5之间的一致的随机值(以像素为单位)?或者也许有人知道使用噪音值的替代方法。
答案 0 :(得分:1)
如何在1.1055228575200001e-012之间获得一个像素为-5的固定随机值?
您可以查看double的内部表示,并将这些位组合成一个int:
int from_noise(double noise)
{
unsigned long long bits;
memcpy(&bits, &noise, 8);
unsigned x = bits ^ (bits >> 32);
return x % 11 - 5;
}
注意:from_noise
假定double
和long long
占用8个字节,int
占用4个字节。此外,该函数将在big-endian和little-endian体系结构上返回不同的结果。
答案 1 :(得分:1)
理想情况下,您可以执行以下操作:
#define RANGE_MIN (-5)
#define RANGE_MAX (+5)
#define RESOLUTION (1.1055228575200001e-012)
#define NUM_OF_VALUES ((int)((RANGE_MAX-RANGE_MIN)/RESOLUTION))
double GetRandVal()
{
return rand()%NUM_OF_VALUES*RESOLUTION+RANGE_MIN;
}
不幸的是,rand()
的最大返回值通常为32767,而示例中的指定范围和分辨率为9045493661191。因此,您必须多次使用rand()
:
#define RANGE_MIN (-5)
#define RANGE_MAX (+5)
#define RESOLUTION (1.1055228575200001e-012)
#define NUM_OF_VALUES ((unsigned long long)((RANGE_MAX-RANGE_MIN)/RESOLUTION))
int GetNumOfBits(unsigned long long val)
{
int numOfBits = 0;
while (val > 0)
{
numOfBits++;
val >>= 1;
}
return numOfBits;
}
static int numOfBitsInRandMax = GetNumOfBits(RAND_MAX);
static int numOfBitsInNumVals = GetNumOfBits(NUM_OF_VALUES);
static int quotient = numOfBitsInNumVals/numOfBitsInRandMax;
static int remainder = numOfBitsInNumVals%numOfBitsInRandMax;
double GetRandVal()
{
unsigned long long randVal = 0;
for (int i=0; i<quotient; i++)
randVal = (randVal<<numOfBitsInRandMax)|rand();
randVal = (randVal<<remainder)|(rand()&((1<<remainder)-1));
return randVal%NUM_OF_VALUES*RESOLUTION+RANGE_MIN;
}
但请注意,从理论上讲,它会降低真实随机性的水平。
顺便说一句,不要忘记使用srand((unsigned int)time(NULL))
播种RNG ......