rand() function not generating enough random

后端 未结 2 1214
星月不相逢
星月不相逢 2021-01-21 16:17

I am working on an openGL project and my rand function is not giving me a big enough random range. I am tasked with writing a diamond program to where one diamond is centered on

相关标签:
2条回答
  • 2021-01-21 16:46

    As WhozCraig mentioned, seeding your random number generator with the time every time you call myDisplay (...) is a bad idea. This is because time (NULL) has a granularity of 1 second, and in real-time graphics you usually draw your scene more than one time per-second. Thus, you are repeating the same sequence of random numbers every time you call myDisplay (...) when less than 1 second has elapsed.

    Also, using modulo arithmetic on a call to rand (...) adversely affects the quality of the returned values. This is because it changes the probability distribution for numbers occurring. The preferred technique should be to cast rand (...) to float and then divide by RAND_MAX, and then multiply this result by your desired range.

    GLfloat x = rand() % 50 + 10; /* <-- Bad! */
    
    /* Consider this instead */
    GLfloat x = (GLfloat)rand () / RAND_MAX * 50.0f + 10.0f;
    

    Although, come to think of it. Why are you using GLfloat for x and y if you are going to store them in an integer data structure 2 lines later?

    0 讨论(0)
  • 2021-01-21 17:07

    This has no business being in this function:

    srand(time(0));
    

    This should be called once at the beginning of your program (a good place is just inside main()); and most-certainly not in your display routine. Once the seed is set, you should never do it again for your process unless you want to repeat a prior sequence (which by the looks of it, you don't).

    That said, I would strongly advise using the functionality in <random> that comes with your C++11 standard library. With it you can establish distributions (ex: uniform_int_distribution<>) that will do much of your modulo work for you, and correctly account for the problems such things can encounter (Andon pointed out one regarding likeliness of certain numbers based on the modulus).

    Spend some time with <random>. Its worth it. An example that uses the three ranges you're using:

    #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;
    }
    

    Output (obviously varies).

    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
    

    Yeah, it really is just that simple. Like I said, that library is this cat's pajamas. There are many more things it offers, including random normal distributions, different engine backends, etc. I highly encourage you to check into it.

    0 讨论(0)
提交回复
热议问题