C# 绘图,奇怪的行为

发布于 2024-08-18 08:20:41 字数 1028 浏览 5 评论 0原文

下面的代码相当简单 - 它用随机选择的像素填充设计表面 - 没有什么特别的(暂时忽略第二种方法中的 XXXXXXX)。

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)
{
    XXXXXXXXXXXXXXXX

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

我的问题是......

如果你用“Random rnd = new Random();”替换 XXXXXXXXX测试图案完全变成相同颜色的水平条,因此不是随机的。

有人来给我解释一下这是为什么吗?

据我所知,第二次尝试的唯一区别是 GetRandomColour 方法创建并使用 Random 类的新实例,但我不明白这是如何生成水平条的。

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)
{
    XXXXXXXXXXXXXXXX

    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..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

假装爱人 2024-08-25 08:20:41

来自 MSDN

随机数生成开始
从种子值。如果是同一个种子
重复使用,同系列
生成数字。一种方法是
产生不同的序列是为了
种子值与时间相关,因此
每个都制作不同的系列
随机的新实例。默认情况下,
无参构造函数
随机类使用系统时钟
产生其种子值
,而其
参数化构造函数可以采用
基于int32值的数量
当前时间的刻度。然而,
因为时钟的时间是有限的
分辨率,使用无参数
构造函数来创建不同的随机数
紧密连续的对象创建
产生的随机数生成器
相同的随机数序列。
下面的例子说明了
两个随机对象
紧接着实例化
生成一系列相同的随机数
数字。

因此,给定相同的种子,Random 实例将产生相同的数字序列。在您的示例中,由于系统时钟的有限分辨率,使用相同的滴答计数作为种子创建随机实例,从而产生相同的序列。

GetRandomColor() 的连续调用在系统时钟的一个时间片内执行。要对此进行测试,请尝试使用 Thread.Sleep(1) 减慢该方法的速度。您应该看到生成了不同的颜色。

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.

顾忌 2024-08-25 08:20:41

您的应用程序运行速度如此之快,以至于初始化 PRNG 的种子在整个循环中保持不变。

因此它不是真正随机的,因此被称为伪随机数生成器。

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.

鹤舞 2024-08-25 08:20:41

创建时的随机数具有默认种子零。在该函数中重新创建它总是会给出相同的数字。在构造函数中创建它,然后重用以获得不同的随机数。

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.

星光不落少年眉 2024-08-25 08:20:41

随机并不是真正的随机。它们是“伪随机”。您真正所做的一切(从机器的角度来看)就是在起始点一遍又一遍地生成相同的随机数。您真正需要做的是要么向构造函数传递一个“种子”,要么具有更高范围的随机数,您可以调用 Next() 方法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文