Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to random generate fully saturated colors only?

I normally use the following code to generate random colors:

Random rand = new Random();

Color random = Color.FromArgb((int)(rand.NextDouble() * 255), 
                              (int)(rand.NextDouble() * 255), 
                              (int)(rand.NextDouble() * 255));

But most of them look like a variation of gray. How can I restrict the output to only fully saturated colors?

Thanks.

like image 489
abenci Avatar asked Dec 12 '11 15:12

abenci


People also ask

What is a fully saturated colour?

Saturation is sometimes referred to as color intensity, a fully saturated color is one of pure color while a fully desaturated color appears as grey. The saturation of a color isn't constant, it varies depending on factors such as its surroundings and what light the color is seen in.

What makes a color more saturated?

The saturation of a color is determined by a combination of light intensity and how much it is distributed across the spectrum of different wavelengths. The purest (most saturated) color is achieved by using just one wavelength at a high intensity, such as in laser light.

What saturated colors look like?

Key Takeaways. Color saturation is how vivid, rich, or intense a color is. Be careful not to confuse highly saturated colors as being lighter than they really are. There are many different ways to alter the saturation of a color, but be mindful of any changes to the other elements, being hue and value.

Which color is more saturated?

Saturation refers to the purity of the light. The more saturated the stimulus, the stronger the color experience, and the less saturated, the more it appears white or gray or black—that is, achromatic. The classic example of saturation differences concerns the continuum from red to pink.


2 Answers

Theory

Full Saturation (as used by HSL and similar colour schemes) in effect means that you have one RGB value at full, one at 0 and one at any other value.

The reason for this is that the saturation is based on the difference between the highest and lowest colour components and is highest when they are at the extremes. The actual definitions are more complicated (and involve the luminance) but it is sufficient to say that a component of 0 and another of 1 will give max saturation.

Algorithm 1

This leads to a relatively simple way of doing it.

  1. Generate a random number between 0 and 1.
  2. Assign this number randomly to one fo the R, G and B elements.
  3. Randomly assign zero to one of the remaining elements.
  4. set the final element to 1.

This will give you a maximum saturation colour relatively simply.

For implementation it is probably easiest to generate a random number 1 to 6 for the 6 possible choices of which component you assign the 0, 1 and random element to and then use a switch of some kind.

This is the easiest algorithm but not necessarily the easiest implementation due to the choices/branching.

Algorithm 2

Second method as suggested by Jim Mischel based on a similar theory but just implemented a bit differently.

  1. Generate random values for each of the R, G and B components
  2. Find the max component.
  3. Find the min component.
  4. Set max component to 1.
  5. Set min component to 0.

This has the same effect of setting one value to 1, one to 0 and one to a random value. It has the advantage that it doesn't require you to use the messy switch statement but you might end up with some messy loops instead. Also depending on the precision of your components (eg if you go straight in with bytes) then if your mid value is actually equal to your top or bottom (or all three are the same) then this might get reset too depending on how you code your algorithm. This will mainly have the effect of skewing the randomness but this is not likely to be significantly noticeable.

Code implementation for method two also courtesy of Jim

    int[] rgb = new int[3];
    rgb[0] = rnd.Next(256);  // red
    rgb[1] = rnd.Next(256);  // green
    rgb[2] = rnd.Next(256);  // blue

    // Console.WriteLine("{0},{1},{2}", rgb[0], rgb[1], rgb[2]);

    // find max and min indexes.
    int max, min;

    if (rgb[0] > rgb[1])
    {
        max = (rgb[0] > rgb[2]) ? 0 : 2
        min = (rgb[1] < rgb[2]) ? 1 : 2;
    }
    else
    {
        max = (rgb[1] > rgb[2]) ? 1 : 2;
        int notmax = 1 + max % 2;
        min = (rgb[0] < rgb[notmax]) ? 0 : notmax;
    }
    rgb[max] = 255;
    rgb[min] = 0;

    // Console.WriteLine("{0},{1},{2}", rgb[0], rgb[1], rgb[2]);
like image 177
Chris Avatar answered Sep 17 '22 13:09

Chris


I guess you want to generate your colors in HSL values setting the saturation fixed to it's max value and only randomize the hue and lightness. You can find a class for a HSL color here.

like image 31
AVee Avatar answered Sep 18 '22 13:09

AVee