rand() 函数没有生成足够的随机

rand() function not generating enough random

本文关键字:随机 函数 rand      更新时间:2023-10-16

我正在做一个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中创建它。

这与此功能无关:

srand(time(0));

这应该在程序开始时调用一次(一个好地方就在main()里面);而且肯定不是在你的显示例程中。一旦设置了种子,除非你想重复先前的序列(从表面上看,你不想重复),否则你永远不应该为你的过程再做一次。

也就是说,我强烈建议使用 C++11 标准库附带的<random>功能。有了它,你可以建立分布(例如: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

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

正如 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;

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