C # Рисование, странное поведение - PullRequest
2 голосов
/ 19 января 2010

следующий код довольно прост - он заполняет поверхность проекта случайно выбранными пикселями - ничего особенного (пока игнорируйте 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);
}

У меня вопрос такой ...

если вы замените XXXXXXXXX на "Random rnd = new Random ();" тестовый шаблон полностью превращается в горизонтальные полосы одного цвета и поэтому не является случайным.

Давай, кто-нибудь объяснит мне, почему это так?

Насколько я могу судить, единственная разница во второй попытке состоит в том, что метод GetRandomColour создает и использует новый экземпляр класса Random, но я не вижу, как это делает горизонтальные столбцы ..

Ответы [ 4 ]

7 голосов
/ 19 января 2010

С MSDN :

Начинается генерация случайных чисел от начального значения. Если это же семя используется многократно, та же серия числа генерируются. Один из способов производить разные последовательности, чтобы сделать начальное значение зависит от времени, тем самым производя разные серии с каждым новый экземпляр Random. По умолчанию, беспараметрический конструктор Случайный класс использует системные часы для генерировать его начальное значение , в то время как его параметризованный конструктор может принять Значение Int32 на основе количества тики в текущее время. Тем не мение, потому что часы имеют конечное разрешение, используя без параметров конструктор для создания различных случайных объекты в тесной последовательности создает генераторы случайных чисел, которые производят идентичные последовательности случайных чисел. Следующий пример показывает, что два случайных объекта, которые создан в тесной последовательности генерировать идентичные серии случайных число.

Итак, при одинаковом начальном значении случайный экземпляр будет производить ту же последовательность чисел. А в вашем примере из-за конечного разрешения системных часов экземпляры Random были созданы с использованием того же числа тиков, что и seed, что привело к той же последовательности.

Последовательные вызовы GetRandomColor() выполняются в течение одного временного интервала системных часов. Чтобы проверить это, попробуйте замедлить метод с помощью Thread.Sleep(1). Вы должны увидеть разные цвета.

3 голосов
/ 19 января 2010

Ваше приложение работает так быстро, что начальное число, с которым инициализируется PRNG, остается неизменным на протяжении всего цикла.

Таким образом, он не является действительно случайным, отсюда и название генератора псевдослучайных чисел.

1 голос
/ 19 января 2010

Рандомы на самом деле не случайны. Они "Psuedo-random" . Все, что вы действительно делаете (с точки зрения машины), это генерирует одно и то же случайное число в исходной точке снова и снова. Что вам действительно нужно сделать, так это либо передать конструктору «начальное число», либо использовать случайный случай с более высокой областью действия, который можно вызвать методом Next ().

1 голос
/ 19 января 2010

Случайные значения при создании имеют начальный ноль по умолчанию. Повторное создание этой функции всегда дает одинаковое число. Создайте его в конструкторе и используйте повторно, чтобы получить разные случайные числа.

...