Why do I get this particular color pattern when using rand()?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
8
down vote

favorite
2












I tried to create a bmp file, like this:



 uint8_t raw_r[pixel_width][pixel_height];
uint8_t raw_g[pixel_width][pixel_height];
uint8_t raw_b[pixel_width][pixel_height];
uint8_t blue(uint32_t x, uint32_t y)

return (rand()%2)? (x+y)%rand() : ((x*y%1024)%rand())%2 ? (x-y)%rand() : rand();

uint8_t green(uint32_t x, uint32_t y)

return (rand()%2)? (x-y)%rand() : ((x*y%1024)%rand())%2 ? (x+y)%rand() : rand();

uint8_t red(uint32_t x, uint32_t y)

return (rand()%2)? (y-x)%rand() : ((x*y%1024)%rand())%2 ? (x+y)%rand() : rand();


for (y=0; y<pixel_height; ++y)

for (x=0; x<pixel_width; ++x)

raw_b[x][y]=blue(x, y);
raw_g[x][y]=green(x, y);
raw_r[x][y]=red(x, y);




I excepted to get something random (white noise).
However, the output is interesting:



enter image description here



Do you know the reason why?










share|improve this question























  • cos rand isnt rand - nice demo of it. It is 100% deterministic
    – pm100
    1 hour ago






  • 1




    stackoverflow.com/questions/822323/…
    – pm100
    1 hour ago










  • also nice answer here regarding randomness stackoverflow.com/questions/3956478/understanding-randomness
    – pm100
    1 hour ago














up vote
8
down vote

favorite
2












I tried to create a bmp file, like this:



 uint8_t raw_r[pixel_width][pixel_height];
uint8_t raw_g[pixel_width][pixel_height];
uint8_t raw_b[pixel_width][pixel_height];
uint8_t blue(uint32_t x, uint32_t y)

return (rand()%2)? (x+y)%rand() : ((x*y%1024)%rand())%2 ? (x-y)%rand() : rand();

uint8_t green(uint32_t x, uint32_t y)

return (rand()%2)? (x-y)%rand() : ((x*y%1024)%rand())%2 ? (x+y)%rand() : rand();

uint8_t red(uint32_t x, uint32_t y)

return (rand()%2)? (y-x)%rand() : ((x*y%1024)%rand())%2 ? (x+y)%rand() : rand();


for (y=0; y<pixel_height; ++y)

for (x=0; x<pixel_width; ++x)

raw_b[x][y]=blue(x, y);
raw_g[x][y]=green(x, y);
raw_r[x][y]=red(x, y);




I excepted to get something random (white noise).
However, the output is interesting:



enter image description here



Do you know the reason why?










share|improve this question























  • cos rand isnt rand - nice demo of it. It is 100% deterministic
    – pm100
    1 hour ago






  • 1




    stackoverflow.com/questions/822323/…
    – pm100
    1 hour ago










  • also nice answer here regarding randomness stackoverflow.com/questions/3956478/understanding-randomness
    – pm100
    1 hour ago












up vote
8
down vote

favorite
2









up vote
8
down vote

favorite
2






2





I tried to create a bmp file, like this:



 uint8_t raw_r[pixel_width][pixel_height];
uint8_t raw_g[pixel_width][pixel_height];
uint8_t raw_b[pixel_width][pixel_height];
uint8_t blue(uint32_t x, uint32_t y)

return (rand()%2)? (x+y)%rand() : ((x*y%1024)%rand())%2 ? (x-y)%rand() : rand();

uint8_t green(uint32_t x, uint32_t y)

return (rand()%2)? (x-y)%rand() : ((x*y%1024)%rand())%2 ? (x+y)%rand() : rand();

uint8_t red(uint32_t x, uint32_t y)

return (rand()%2)? (y-x)%rand() : ((x*y%1024)%rand())%2 ? (x+y)%rand() : rand();


for (y=0; y<pixel_height; ++y)

for (x=0; x<pixel_width; ++x)

raw_b[x][y]=blue(x, y);
raw_g[x][y]=green(x, y);
raw_r[x][y]=red(x, y);




I excepted to get something random (white noise).
However, the output is interesting:



enter image description here



Do you know the reason why?










share|improve this question















I tried to create a bmp file, like this:



 uint8_t raw_r[pixel_width][pixel_height];
uint8_t raw_g[pixel_width][pixel_height];
uint8_t raw_b[pixel_width][pixel_height];
uint8_t blue(uint32_t x, uint32_t y)

return (rand()%2)? (x+y)%rand() : ((x*y%1024)%rand())%2 ? (x-y)%rand() : rand();

uint8_t green(uint32_t x, uint32_t y)

return (rand()%2)? (x-y)%rand() : ((x*y%1024)%rand())%2 ? (x+y)%rand() : rand();

uint8_t red(uint32_t x, uint32_t y)

return (rand()%2)? (y-x)%rand() : ((x*y%1024)%rand())%2 ? (x+y)%rand() : rand();


for (y=0; y<pixel_height; ++y)

for (x=0; x<pixel_width; ++x)

raw_b[x][y]=blue(x, y);
raw_g[x][y]=green(x, y);
raw_r[x][y]=red(x, y);




I excepted to get something random (white noise).
However, the output is interesting:



enter image description here



Do you know the reason why?







c random






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 1 hour ago









templatetypedef

254k65634868




254k65634868










asked 2 hours ago









Little Pony

574




574











  • cos rand isnt rand - nice demo of it. It is 100% deterministic
    – pm100
    1 hour ago






  • 1




    stackoverflow.com/questions/822323/…
    – pm100
    1 hour ago










  • also nice answer here regarding randomness stackoverflow.com/questions/3956478/understanding-randomness
    – pm100
    1 hour ago
















  • cos rand isnt rand - nice demo of it. It is 100% deterministic
    – pm100
    1 hour ago






  • 1




    stackoverflow.com/questions/822323/…
    – pm100
    1 hour ago










  • also nice answer here regarding randomness stackoverflow.com/questions/3956478/understanding-randomness
    – pm100
    1 hour ago















cos rand isnt rand - nice demo of it. It is 100% deterministic
– pm100
1 hour ago




cos rand isnt rand - nice demo of it. It is 100% deterministic
– pm100
1 hour ago




1




1




stackoverflow.com/questions/822323/…
– pm100
1 hour ago




stackoverflow.com/questions/822323/…
– pm100
1 hour ago












also nice answer here regarding randomness stackoverflow.com/questions/3956478/understanding-randomness
– pm100
1 hour ago




also nice answer here regarding randomness stackoverflow.com/questions/3956478/understanding-randomness
– pm100
1 hour ago












2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










I was initially going to have the same answer as everyone else had and chalk this up to the issues with rand(), however I thought better of doing so and instead analyzed the distribution your math is actually producing.



TL;DR: The pattern you see has nothing to do with the underlying random number generator and instead is simply due to the way your program is manipulating the numbers.



I'll stick to your blue function since they're all similar.



uint8_t blue(uint32_t x, uint32_t y) 
return (rand() % 2) ? (x + y) % rand() :
((x * y % 1024) % rand()) % 2 ? (x - y) % rand() :
rand();



Each pixel value is selected from one of three functions: (x + y) % rand(), (x - y) % rand(), and rand();



Let's look at images produced by each of these alone.



  • rand()

This is what you would expect, just noise.



enter image description here




  • (x + y) % rand()

Here you're adding the pixel coordinates together and taking the remainder from dividing by a random number. If the image is 1024x1024 then the sum is in the range [0-2046]. The random number you're diving by is in the range [0,RAND_MAX], where RAND_MAX is at least 32k and on some systems is 2 billion. In other words there's at best a 1 in 16 chance that the remainder isn't just (x + y). So for the most part this function will just produce a gradient of increasing blue toward the +x +y direction.



However you're only using the lowest 8 bits, because you return a uint8_t, so you'll have stripes of gradients 256 pixels wide.



enter image description here




  • (x - y) % rand()

Here you do something similar, but with subtraction. As long as x is greater than y you'll have something similar to the previous image. But where y is greater, the result is a very large number because x and y are unsigned (negative results wrap around to the top of the unsigned types range), and then the the % rand() kicks in and you actually get noise.



enter image description here



Then you pick from these images using functions rand() % 2 and ((x * y % 1024) % rand()) % 2. The first of these can be read as choosing with 50% probabilty (ignoring issues with rand() and its low order bits.)



The second again has the issue where rand() is usually greater than the thing you're dividing, which is at most 1023. But (x*y%1024)%2 doesn't produce 0 and 1 equally often. Any odd number multiplied by any even number is even. Any even number multiplied by any even number is also even. Only an odd number multiplied by an odd number is odd, and so %2 on values that are even three quarters of the time will produce 0 three quarters of the time.



So your the resulting combination can be read as:



With 50% probability use the pixel from striped image. The rest of the time pick between noise (on pixels where either coordinate is even). On the remaining one eighth of pixels take the pixel from the half striped, half noise picture.



Finally, since you're doing the same for three different colors, but with different orientations, etc. the patterns are oriented differently in each color and produce the crossing strips or grid pattern you're seeing.






share|improve this answer





























    up vote
    8
    down vote













    Many of the calculations that you're doing in your code won't lead to truly random values. Those sharp lines that you're seeing correspond to places where the relative values of your x and y coordinates trade with one another, and when that happens you're using fundamentally different formulas. For example, computing (x + y) % rand() will generally give you back the value x + y, since rand() will (usually) return a number much, much bigger than x + y given that RAND_MAX is usually a fairly large number. In that sense, you shouldn't expect to get back white noise, since the algorithm you're using to generate things is biased away from generating white noise. If you want white noise, just set each pixel to rand(). If you'd like a nice pattern like the one you have above, but with a little bit of randomness tossed in here and there, keep using the code that you have written.



    Additionally, as @pm100 has noted in the comments, the rand function doesn't return truly random numbers, and instead uses a pseudorandom function to produce it values. The default implementation of rand on many systems uses a type of pseudorandom number generator called a linear congruential generator that produces numbers that in short bursts can appear random, but which are decidedly nonrandom in practice. For example, here's an animation from Wikipedia showing how random points in space chosen with a linear congruential generator end up falling into a fixed number of hyperplanes:



    The image



    If you replace x, y, and z coordinates with R, G, and B coordinates, this looks remarkably similar to the output being produced by your program. I suspect that this is probably not the core issue here, since the other aspect mentioned above will probably be much more pronounced.



    If you're looking for higher-quality random numbers, you'll need to use a higher-quality random source. In C, you could consider reading bytes from /dev/urandom/ (on a Linux-like system), which gives fairly uniformly random values. C++ now has a number of good random-number generation primitives in its standard libraries, if that's available to you.






    share|improve this answer






















    • awesome answer.
      – pm100
      1 hour ago










    Your Answer





    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52451998%2fwhy-do-i-get-this-particular-color-pattern-when-using-rand%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote



    accepted










    I was initially going to have the same answer as everyone else had and chalk this up to the issues with rand(), however I thought better of doing so and instead analyzed the distribution your math is actually producing.



    TL;DR: The pattern you see has nothing to do with the underlying random number generator and instead is simply due to the way your program is manipulating the numbers.



    I'll stick to your blue function since they're all similar.



    uint8_t blue(uint32_t x, uint32_t y) 
    return (rand() % 2) ? (x + y) % rand() :
    ((x * y % 1024) % rand()) % 2 ? (x - y) % rand() :
    rand();



    Each pixel value is selected from one of three functions: (x + y) % rand(), (x - y) % rand(), and rand();



    Let's look at images produced by each of these alone.



    • rand()

    This is what you would expect, just noise.



    enter image description here




    • (x + y) % rand()

    Here you're adding the pixel coordinates together and taking the remainder from dividing by a random number. If the image is 1024x1024 then the sum is in the range [0-2046]. The random number you're diving by is in the range [0,RAND_MAX], where RAND_MAX is at least 32k and on some systems is 2 billion. In other words there's at best a 1 in 16 chance that the remainder isn't just (x + y). So for the most part this function will just produce a gradient of increasing blue toward the +x +y direction.



    However you're only using the lowest 8 bits, because you return a uint8_t, so you'll have stripes of gradients 256 pixels wide.



    enter image description here




    • (x - y) % rand()

    Here you do something similar, but with subtraction. As long as x is greater than y you'll have something similar to the previous image. But where y is greater, the result is a very large number because x and y are unsigned (negative results wrap around to the top of the unsigned types range), and then the the % rand() kicks in and you actually get noise.



    enter image description here



    Then you pick from these images using functions rand() % 2 and ((x * y % 1024) % rand()) % 2. The first of these can be read as choosing with 50% probabilty (ignoring issues with rand() and its low order bits.)



    The second again has the issue where rand() is usually greater than the thing you're dividing, which is at most 1023. But (x*y%1024)%2 doesn't produce 0 and 1 equally often. Any odd number multiplied by any even number is even. Any even number multiplied by any even number is also even. Only an odd number multiplied by an odd number is odd, and so %2 on values that are even three quarters of the time will produce 0 three quarters of the time.



    So your the resulting combination can be read as:



    With 50% probability use the pixel from striped image. The rest of the time pick between noise (on pixels where either coordinate is even). On the remaining one eighth of pixels take the pixel from the half striped, half noise picture.



    Finally, since you're doing the same for three different colors, but with different orientations, etc. the patterns are oriented differently in each color and produce the crossing strips or grid pattern you're seeing.






    share|improve this answer


























      up vote
      2
      down vote



      accepted










      I was initially going to have the same answer as everyone else had and chalk this up to the issues with rand(), however I thought better of doing so and instead analyzed the distribution your math is actually producing.



      TL;DR: The pattern you see has nothing to do with the underlying random number generator and instead is simply due to the way your program is manipulating the numbers.



      I'll stick to your blue function since they're all similar.



      uint8_t blue(uint32_t x, uint32_t y) 
      return (rand() % 2) ? (x + y) % rand() :
      ((x * y % 1024) % rand()) % 2 ? (x - y) % rand() :
      rand();



      Each pixel value is selected from one of three functions: (x + y) % rand(), (x - y) % rand(), and rand();



      Let's look at images produced by each of these alone.



      • rand()

      This is what you would expect, just noise.



      enter image description here




      • (x + y) % rand()

      Here you're adding the pixel coordinates together and taking the remainder from dividing by a random number. If the image is 1024x1024 then the sum is in the range [0-2046]. The random number you're diving by is in the range [0,RAND_MAX], where RAND_MAX is at least 32k and on some systems is 2 billion. In other words there's at best a 1 in 16 chance that the remainder isn't just (x + y). So for the most part this function will just produce a gradient of increasing blue toward the +x +y direction.



      However you're only using the lowest 8 bits, because you return a uint8_t, so you'll have stripes of gradients 256 pixels wide.



      enter image description here




      • (x - y) % rand()

      Here you do something similar, but with subtraction. As long as x is greater than y you'll have something similar to the previous image. But where y is greater, the result is a very large number because x and y are unsigned (negative results wrap around to the top of the unsigned types range), and then the the % rand() kicks in and you actually get noise.



      enter image description here



      Then you pick from these images using functions rand() % 2 and ((x * y % 1024) % rand()) % 2. The first of these can be read as choosing with 50% probabilty (ignoring issues with rand() and its low order bits.)



      The second again has the issue where rand() is usually greater than the thing you're dividing, which is at most 1023. But (x*y%1024)%2 doesn't produce 0 and 1 equally often. Any odd number multiplied by any even number is even. Any even number multiplied by any even number is also even. Only an odd number multiplied by an odd number is odd, and so %2 on values that are even three quarters of the time will produce 0 three quarters of the time.



      So your the resulting combination can be read as:



      With 50% probability use the pixel from striped image. The rest of the time pick between noise (on pixels where either coordinate is even). On the remaining one eighth of pixels take the pixel from the half striped, half noise picture.



      Finally, since you're doing the same for three different colors, but with different orientations, etc. the patterns are oriented differently in each color and produce the crossing strips or grid pattern you're seeing.






      share|improve this answer
























        up vote
        2
        down vote



        accepted







        up vote
        2
        down vote



        accepted






        I was initially going to have the same answer as everyone else had and chalk this up to the issues with rand(), however I thought better of doing so and instead analyzed the distribution your math is actually producing.



        TL;DR: The pattern you see has nothing to do with the underlying random number generator and instead is simply due to the way your program is manipulating the numbers.



        I'll stick to your blue function since they're all similar.



        uint8_t blue(uint32_t x, uint32_t y) 
        return (rand() % 2) ? (x + y) % rand() :
        ((x * y % 1024) % rand()) % 2 ? (x - y) % rand() :
        rand();



        Each pixel value is selected from one of three functions: (x + y) % rand(), (x - y) % rand(), and rand();



        Let's look at images produced by each of these alone.



        • rand()

        This is what you would expect, just noise.



        enter image description here




        • (x + y) % rand()

        Here you're adding the pixel coordinates together and taking the remainder from dividing by a random number. If the image is 1024x1024 then the sum is in the range [0-2046]. The random number you're diving by is in the range [0,RAND_MAX], where RAND_MAX is at least 32k and on some systems is 2 billion. In other words there's at best a 1 in 16 chance that the remainder isn't just (x + y). So for the most part this function will just produce a gradient of increasing blue toward the +x +y direction.



        However you're only using the lowest 8 bits, because you return a uint8_t, so you'll have stripes of gradients 256 pixels wide.



        enter image description here




        • (x - y) % rand()

        Here you do something similar, but with subtraction. As long as x is greater than y you'll have something similar to the previous image. But where y is greater, the result is a very large number because x and y are unsigned (negative results wrap around to the top of the unsigned types range), and then the the % rand() kicks in and you actually get noise.



        enter image description here



        Then you pick from these images using functions rand() % 2 and ((x * y % 1024) % rand()) % 2. The first of these can be read as choosing with 50% probabilty (ignoring issues with rand() and its low order bits.)



        The second again has the issue where rand() is usually greater than the thing you're dividing, which is at most 1023. But (x*y%1024)%2 doesn't produce 0 and 1 equally often. Any odd number multiplied by any even number is even. Any even number multiplied by any even number is also even. Only an odd number multiplied by an odd number is odd, and so %2 on values that are even three quarters of the time will produce 0 three quarters of the time.



        So your the resulting combination can be read as:



        With 50% probability use the pixel from striped image. The rest of the time pick between noise (on pixels where either coordinate is even). On the remaining one eighth of pixels take the pixel from the half striped, half noise picture.



        Finally, since you're doing the same for three different colors, but with different orientations, etc. the patterns are oriented differently in each color and produce the crossing strips or grid pattern you're seeing.






        share|improve this answer














        I was initially going to have the same answer as everyone else had and chalk this up to the issues with rand(), however I thought better of doing so and instead analyzed the distribution your math is actually producing.



        TL;DR: The pattern you see has nothing to do with the underlying random number generator and instead is simply due to the way your program is manipulating the numbers.



        I'll stick to your blue function since they're all similar.



        uint8_t blue(uint32_t x, uint32_t y) 
        return (rand() % 2) ? (x + y) % rand() :
        ((x * y % 1024) % rand()) % 2 ? (x - y) % rand() :
        rand();



        Each pixel value is selected from one of three functions: (x + y) % rand(), (x - y) % rand(), and rand();



        Let's look at images produced by each of these alone.



        • rand()

        This is what you would expect, just noise.



        enter image description here




        • (x + y) % rand()

        Here you're adding the pixel coordinates together and taking the remainder from dividing by a random number. If the image is 1024x1024 then the sum is in the range [0-2046]. The random number you're diving by is in the range [0,RAND_MAX], where RAND_MAX is at least 32k and on some systems is 2 billion. In other words there's at best a 1 in 16 chance that the remainder isn't just (x + y). So for the most part this function will just produce a gradient of increasing blue toward the +x +y direction.



        However you're only using the lowest 8 bits, because you return a uint8_t, so you'll have stripes of gradients 256 pixels wide.



        enter image description here




        • (x - y) % rand()

        Here you do something similar, but with subtraction. As long as x is greater than y you'll have something similar to the previous image. But where y is greater, the result is a very large number because x and y are unsigned (negative results wrap around to the top of the unsigned types range), and then the the % rand() kicks in and you actually get noise.



        enter image description here



        Then you pick from these images using functions rand() % 2 and ((x * y % 1024) % rand()) % 2. The first of these can be read as choosing with 50% probabilty (ignoring issues with rand() and its low order bits.)



        The second again has the issue where rand() is usually greater than the thing you're dividing, which is at most 1023. But (x*y%1024)%2 doesn't produce 0 and 1 equally often. Any odd number multiplied by any even number is even. Any even number multiplied by any even number is also even. Only an odd number multiplied by an odd number is odd, and so %2 on values that are even three quarters of the time will produce 0 three quarters of the time.



        So your the resulting combination can be read as:



        With 50% probability use the pixel from striped image. The rest of the time pick between noise (on pixels where either coordinate is even). On the remaining one eighth of pixels take the pixel from the half striped, half noise picture.



        Finally, since you're doing the same for three different colors, but with different orientations, etc. the patterns are oriented differently in each color and produce the crossing strips or grid pattern you're seeing.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 19 mins ago

























        answered 42 mins ago









        bames53

        65.8k5124189




        65.8k5124189






















            up vote
            8
            down vote













            Many of the calculations that you're doing in your code won't lead to truly random values. Those sharp lines that you're seeing correspond to places where the relative values of your x and y coordinates trade with one another, and when that happens you're using fundamentally different formulas. For example, computing (x + y) % rand() will generally give you back the value x + y, since rand() will (usually) return a number much, much bigger than x + y given that RAND_MAX is usually a fairly large number. In that sense, you shouldn't expect to get back white noise, since the algorithm you're using to generate things is biased away from generating white noise. If you want white noise, just set each pixel to rand(). If you'd like a nice pattern like the one you have above, but with a little bit of randomness tossed in here and there, keep using the code that you have written.



            Additionally, as @pm100 has noted in the comments, the rand function doesn't return truly random numbers, and instead uses a pseudorandom function to produce it values. The default implementation of rand on many systems uses a type of pseudorandom number generator called a linear congruential generator that produces numbers that in short bursts can appear random, but which are decidedly nonrandom in practice. For example, here's an animation from Wikipedia showing how random points in space chosen with a linear congruential generator end up falling into a fixed number of hyperplanes:



            The image



            If you replace x, y, and z coordinates with R, G, and B coordinates, this looks remarkably similar to the output being produced by your program. I suspect that this is probably not the core issue here, since the other aspect mentioned above will probably be much more pronounced.



            If you're looking for higher-quality random numbers, you'll need to use a higher-quality random source. In C, you could consider reading bytes from /dev/urandom/ (on a Linux-like system), which gives fairly uniformly random values. C++ now has a number of good random-number generation primitives in its standard libraries, if that's available to you.






            share|improve this answer






















            • awesome answer.
              – pm100
              1 hour ago














            up vote
            8
            down vote













            Many of the calculations that you're doing in your code won't lead to truly random values. Those sharp lines that you're seeing correspond to places where the relative values of your x and y coordinates trade with one another, and when that happens you're using fundamentally different formulas. For example, computing (x + y) % rand() will generally give you back the value x + y, since rand() will (usually) return a number much, much bigger than x + y given that RAND_MAX is usually a fairly large number. In that sense, you shouldn't expect to get back white noise, since the algorithm you're using to generate things is biased away from generating white noise. If you want white noise, just set each pixel to rand(). If you'd like a nice pattern like the one you have above, but with a little bit of randomness tossed in here and there, keep using the code that you have written.



            Additionally, as @pm100 has noted in the comments, the rand function doesn't return truly random numbers, and instead uses a pseudorandom function to produce it values. The default implementation of rand on many systems uses a type of pseudorandom number generator called a linear congruential generator that produces numbers that in short bursts can appear random, but which are decidedly nonrandom in practice. For example, here's an animation from Wikipedia showing how random points in space chosen with a linear congruential generator end up falling into a fixed number of hyperplanes:



            The image



            If you replace x, y, and z coordinates with R, G, and B coordinates, this looks remarkably similar to the output being produced by your program. I suspect that this is probably not the core issue here, since the other aspect mentioned above will probably be much more pronounced.



            If you're looking for higher-quality random numbers, you'll need to use a higher-quality random source. In C, you could consider reading bytes from /dev/urandom/ (on a Linux-like system), which gives fairly uniformly random values. C++ now has a number of good random-number generation primitives in its standard libraries, if that's available to you.






            share|improve this answer






















            • awesome answer.
              – pm100
              1 hour ago












            up vote
            8
            down vote










            up vote
            8
            down vote









            Many of the calculations that you're doing in your code won't lead to truly random values. Those sharp lines that you're seeing correspond to places where the relative values of your x and y coordinates trade with one another, and when that happens you're using fundamentally different formulas. For example, computing (x + y) % rand() will generally give you back the value x + y, since rand() will (usually) return a number much, much bigger than x + y given that RAND_MAX is usually a fairly large number. In that sense, you shouldn't expect to get back white noise, since the algorithm you're using to generate things is biased away from generating white noise. If you want white noise, just set each pixel to rand(). If you'd like a nice pattern like the one you have above, but with a little bit of randomness tossed in here and there, keep using the code that you have written.



            Additionally, as @pm100 has noted in the comments, the rand function doesn't return truly random numbers, and instead uses a pseudorandom function to produce it values. The default implementation of rand on many systems uses a type of pseudorandom number generator called a linear congruential generator that produces numbers that in short bursts can appear random, but which are decidedly nonrandom in practice. For example, here's an animation from Wikipedia showing how random points in space chosen with a linear congruential generator end up falling into a fixed number of hyperplanes:



            The image



            If you replace x, y, and z coordinates with R, G, and B coordinates, this looks remarkably similar to the output being produced by your program. I suspect that this is probably not the core issue here, since the other aspect mentioned above will probably be much more pronounced.



            If you're looking for higher-quality random numbers, you'll need to use a higher-quality random source. In C, you could consider reading bytes from /dev/urandom/ (on a Linux-like system), which gives fairly uniformly random values. C++ now has a number of good random-number generation primitives in its standard libraries, if that's available to you.






            share|improve this answer














            Many of the calculations that you're doing in your code won't lead to truly random values. Those sharp lines that you're seeing correspond to places where the relative values of your x and y coordinates trade with one another, and when that happens you're using fundamentally different formulas. For example, computing (x + y) % rand() will generally give you back the value x + y, since rand() will (usually) return a number much, much bigger than x + y given that RAND_MAX is usually a fairly large number. In that sense, you shouldn't expect to get back white noise, since the algorithm you're using to generate things is biased away from generating white noise. If you want white noise, just set each pixel to rand(). If you'd like a nice pattern like the one you have above, but with a little bit of randomness tossed in here and there, keep using the code that you have written.



            Additionally, as @pm100 has noted in the comments, the rand function doesn't return truly random numbers, and instead uses a pseudorandom function to produce it values. The default implementation of rand on many systems uses a type of pseudorandom number generator called a linear congruential generator that produces numbers that in short bursts can appear random, but which are decidedly nonrandom in practice. For example, here's an animation from Wikipedia showing how random points in space chosen with a linear congruential generator end up falling into a fixed number of hyperplanes:



            The image



            If you replace x, y, and z coordinates with R, G, and B coordinates, this looks remarkably similar to the output being produced by your program. I suspect that this is probably not the core issue here, since the other aspect mentioned above will probably be much more pronounced.



            If you're looking for higher-quality random numbers, you'll need to use a higher-quality random source. In C, you could consider reading bytes from /dev/urandom/ (on a Linux-like system), which gives fairly uniformly random values. C++ now has a number of good random-number generation primitives in its standard libraries, if that's available to you.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 1 hour ago

























            answered 1 hour ago









            templatetypedef

            254k65634868




            254k65634868











            • awesome answer.
              – pm100
              1 hour ago
















            • awesome answer.
              – pm100
              1 hour ago















            awesome answer.
            – pm100
            1 hour ago




            awesome answer.
            – pm100
            1 hour ago

















             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52451998%2fwhy-do-i-get-this-particular-color-pattern-when-using-rand%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            Long meetings (6-7 hours a day): Being “babysat” by supervisor

            Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

            Confectionery