Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explanation for interesting phenomenom with Random() and colors

A student of mine had a cool result which I just couldn't explain. In her code, she wants to create random circles (in WPF) with Random colors. She made the typical beginner's mistake of creating more than one Random generator, but bear with me, please.

This is the code:

        Random cir = new Random();
        Random color = new Random();

        for (i = 0; i < 100; i++)
        {
            int r = cir.Next(0, 50);
            diameter = r * 2;
            int posx = cir.Next(0, (510 - diameter));
            int posy = cir.Next(0, (280 - diameter ));


            byte c1 = (byte)color.Next(255);
            byte c2 = (byte)color.Next(255);
            byte c3 = (byte)color.Next(255);
            SolidColorBrush usedcolor = new SolidColorBrush(Color.FromRgb(c1,c2,c3

               ));
            Ellipse circle = new Ellipse();
            circle.Height = diameter;
            circle.Width = diameter;
            circle.Margin = new Thickness(posx, posy, 0, 0);
            circle.Stroke = usedcolor;
            // melkweg.StrokeThickness = dikte;

            Ruimte.Children.Add(circle);
        }

This will always generate the same effect: the colors appear to be 'grouped' , you'll always get the same colors in the same region. Two examples: enter image description here

I understand that the two Random generators are created at the quasi-exact same moment and so have the same seed and are basically 'in sync'. However, since we demand different ranges every Next I was thinking this would result in non-correlated numbers, but I am clearly wrong. (has the Range no impact? Does Random.Next just always generates a number between 0 and 1 and then expands it (denormalise?) it to the desired range? )

Even by simply calling one more Next() on cir or color (e.g. color.Next(1);) will generate a completely random figure as desired, and not the cool, but unwanted effect.

So my main question is, why are those colors "grouped" and what aspect of the random number generation and 'synced' generators am I missing?

Hope this explanation is full and someone can help me out. Thanks a bunch!

PS Here's the desired output (using 1 Random, or adding a useless Next()-call) enter image description here

like image 821
Tim Dams Avatar asked Dec 01 '16 10:12

Tim Dams


People also ask

What is a natural phenomenon in science?

Natural Phenomenon Definition A natural phenomenon is defined as an extraordinary occurrence in nature that can be scientifically verified. Natural phenomena are often recognized for their exceptional beauty, tremendous power, rarity, and organized intelligence. What are some natural phenomena?

What is the difference between social phenomenon and psychological phenomenon?

Social phenomena are those that occur or exist through the actions of groups of humans. Six degrees of separation, for example, is a phenomenon that is demonstrated in social networking. Psychological phenomena are those manifested in human behaviors and responses.

How do colors affect our perception of color?

The perception and effects of colors depend on their context. This is why a particular red may appear much redder when adjacent to green than when surrounded by a gray background —the surrounding green or gray changes how that red is perceived.

What is an example of a social phenomenon?

Here are a few of the many possibilities, with examples: Natural phenomena are those that occur or manifest without human input. Examples of natural phenomena include gravity, tides, biological processes and oscillation. Social phenomena are those that occur or exist through the actions of groups of humans.


1 Answers

So Random.Next(int min, int max) works approximately as follows:

  1. Generate random integer in the full integer range
  2. Map that to double in 0 .. 1 range.
  3. Expand that double to your range (double * (max - min)) + min

What that means is if you have two randoms with the same seed, parallel calls to them will generate perfectly correlated values, whatever ranges you use.

var r1 = new Random(2);
var r2 = new Random(2);
Console.WriteLine(r1.Next(0, 10)); // 7
Console.WriteLine(r1.Next(0, 10)); // 4
Console.WriteLine(r1.Next(0, 10)); // 1

Console.WriteLine(r2.Next(0, 20)); // 15
Console.WriteLine(r2.Next(0, 20)); // 8
Console.WriteLine(r2.Next(0, 20)); // 3

In your example you have two randoms with the same seed and you call each of them exactly 3 times on each loop iteration. What effect this has?

  1. Radius and R part of color has strong correlation
  2. X coordinate and G part of color has strong correlation (whenver X is large - G is also large, and visa versa).
  3. Y coordinate and B part of color has strong correlation. (whenever Y is large, B is also large, and visa versa).

From that I think it's obvious why circles are grouped together by color (G and B parts).

Whenever you add one more Random.Next call to any of the randoms - it breaks perfect 3 + 3 calls correlation, so effect disappears (though if you make Random.Next calls for both randoms, you will have the same effect again).

like image 80
Evk Avatar answered Nov 04 '22 00:11

Evk