把小双变成int

时间:2014-04-21 07:00:30

标签: c++ terrain

我使用libnoise生成2D精灵forrests。 enter image description here

然后我让我的世界更大,我目前在世界范围内工作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之间的一致的随机值(以像素为单位)?或者也许有人知道使用噪音值的替代方法。

2 个答案:

答案 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假定doublelong 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 ......