开发者

C# Drawing, Strange Behaviour

开发者 https://www.devze.com 2022-12-17 08:07 出处:网络
the following code is fairly straight forward - it fills a design surface with randomnly selected pixels - nothing special (ignore the XXXXXXX\'s in the 2nd method for now).

the following code is fairly straight forward - it fills a design surface with randomnly selected pixels - nothing special (ignore the XXXXXXX's in the 2nd method for now).

private void PaintBackground()
{
    Random rnd = new Random();

    Bitmap b = new Bitmap(this.Width, this.Height);
    for (int vertical = 0; vertical < this.Height; vertical++)
    {
        for (int horizontal = 0; horizontal < this.Width; horizontal++)
        {
            Color randomColour = GetRandomColor(rnd);
            b.SetPixel(horizontal, vertical, randomColour);
        }
    }

    Graphics g = this.CreateGraphics();
    g.DrawImage(b, new Point(0, 0));
}

public Color GetRandomColor(Random rnd)
{
    XXX开发者_开发百科XXXXXXXXXXXXX

    byte r = Convert.ToByte(rnd.Next(0, 255));
    byte g = Convert.ToByte(rnd.Next(0, 255));
    byte b = Convert.ToByte(rnd.Next(0, 255));

    return Color.FromArgb(255, r, g, b);
}

The question i have is this...

if you replace the XXXXXXXXX with "Random rnd = new Random();" the test pattern completely changes into horizontal bars of the same colour, and is therefore not random.

Come someone explain to me why this is?

As far as I can tell the only difference in the second attempt is that the GetRandomColour method creates and uses a new instance of the Random class but I don't see how that makes horizontal bars..


From MSDN:

The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated. One way to produce different sequences is to make the seed value time-dependent, thereby producing a different series with each new instance of Random. By default, the parameterless constructor of the Random class uses the system clock to generate its seed value, while its parameterized constructor can take an Int32 value based on the number of ticks in the current time. However, because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers. The following example illustrates that two Random objects that are instantiated in close succession generate an identical series of random numbers.

So given the same seed the Random instance will produce the same sequence of numbers. And in your example due to the finite resolution of the system clock, the Random instances were created using the same tick count as seed, resulting in the same sequence.

The consecutive calls to GetRandomColor() are executed within one time slice of the system clock. To test this, try slowing the method down with Thread.Sleep(1). You should see different colors being generated.


Your application runs so fast that the seed the PRNG is being initialized with, stays the same throughout the entire loop.

Thus it is not truly random, hence the name Pseudo Random Number Generator.


Random when created have a default seed zero. Recreating it in that function will always give the same number. Create it in constructor and than reuse to get different random numbers.


Randoms aren't really random. They're "Psuedo-random". All you're really doing (from the machine standpoint) is generating the same random at the origination point over and over again. What you really need to do is either pass the constructor a "seed" or have a higher scoped random that you can call the Next() method.

0

精彩评论

暂无评论...
验证码 换一张
取 消