2

我正在开发一个 openGL 项目,而我的 rand 函数没有给我足够大的随机范围。我的任务是编写一个钻石程序,其中一颗钻石位于屏幕中心,5 颗随机放置在屏幕上的其他位置。正在发生的事情是我的中心钻石在它应该在的位置,而其他五颗正在与中心左侧的一小部分随机排列在一起。我已经包含了绘制钻石的功能。

void myDisplay(void)
{
srand(time(0));

GLintPoint CenterPoint;
int const size = 20;

CenterPoint.x = screenWidth / 2;
CenterPoint.y = screenHeight / 2;

glClear(GL_COLOR_BUFFER_BIT);

drawDiamond(CenterPoint, size);

for (int i = 0; i < 5; i++)
{
    GLfloat x = rand() % 50 + 10;
    GLfloat y = rand() % 200 + 100;
    GLfloat size = rand() % 100;
    GLintPoint diam = {x,y};
    drawDiamond(diam, size);
}

如果需要更多代码,请告诉我,我会编辑。有人对我如何纠正这个有任何想法吗?我已经“玩弄”了 rand() 函数的数字,实际上似乎并没有做太多事情。它们似乎仍然聚集在屏幕上的不同点。我很感激帮助。以防万一有人需要知道,我在 VS2012 中创建它。

4

2 回答 2

10

这与此功能无关:

srand(time(0));

这应该在程序开始时调用一次(一个好地方就在里面main());而且肯定不在您的显示程序中。设置种子后,除非您想重复先前的序列(从外观上看,您不需要),否则您永远不应该为您的流程再次执行此操作。

也就是说,我强烈建议使用<random>C++11 标准库附带的功能。有了它,您可以建立分布(例如:)uniform_int_distribution<>,这将为您完成大部分模数工作,并正确解释此类事情可能遇到的问题(Andon 指出了一个关于基于模数的某些数字的可能性的问题)。

花一些时间与<random>. 这很值得。使用您正在使用的三个范围的示例:

#include <iostream>
#include <random>
using namespace std;

int main()
{
    std::random_device rd;
    std::default_random_engine rng(rd());

    // our distributions.        
    std::uniform_int_distribution<> dist1(50,60);
    std::uniform_int_distribution<> dist2(200,300);
    std::uniform_int_distribution<> dist3(0,100);

    for (int i=0;i<10;++i)
        std::cout << dist1(rng) << ',' << dist2(rng) << ',' << dist3(rng) << std::endl;

    return EXIT_SUCCESS;
}

输出(显然不同)。

58,292,70
56,233,41
57,273,98
52,204,8
50,284,43
51,292,48
53,220,42
54,281,64
50,290,51
53,220,7

是的,真的就是这么简单。就像我说的,那个图书馆就是这只猫的睡衣。它提供更多的东西,包括随机正态分布、不同的引擎后端等。我强烈建议您检查一下。

于 2013-09-08T23:19:24.940 回答
2

正如 WhozCraig 所提到的,每次打电话时都在随机数生成器中播种myDisplay (...)是一个坏主意。这是因为time (NULL)粒度为 1 秒,而在实时图形中,您通常每秒绘制一次以上的场景。myDisplay (...)因此,在不到 1 秒的时间内,您每次调用时都会重复相同的随机数序列。

此外,在调用中使用模运算rand (...)会对返回值的质量产生不利影响。这是因为它改变了数字出现的概率分布。首选技术应该是转换rand (...)为浮点数,然后除以 RAND_MAX,然后将此结果乘以所需范围。

GLfloat x = rand() % 50 + 10; /* <-- Bad! */

/* Consider this instead */
GLfloat x = (GLfloat)rand () / RAND_MAX * 50.0f + 10.0f;

虽然,仔细想想。GLfloat如果要在 2 行之后将它们存储在整数数据结构中,为什么要使用x 和 y?

于 2013-09-08T23:26:45.087 回答