skip to Main Content

I’m trying to generate a rainbow with 15 different colors with (runnable code here):

size(360,100);
colorMode(HSB, 360, 100, 100); // Hue in degrees in [0, 360],
                               // saturation/brightness in [0, 100]
                               // like in Photoshop
noStroke();

for (int i = 0; i < 15; i++)   
{
    fill(i*24, 100, 100);      // 24*15 = 360
    rect(i*24, 0, 25, 100);
}

but it doesn’t produce a rich 15 rainbow-color palette, instead some colors are missing (vivid yellow for example).

enter image description here

Is there a well known algorithm to produce a vivid rainbow color palette?

2

Answers


  1. To understand what’s going on, try creating a program that shows a line for each value 0-360:

    size(360,100);
    colorMode(HSB, 360, 100, 100);                                         
    noStroke();
    for (int i = 0; i < 360; i++)   
    {
        fill(i, 100, 100);
        rect(i, 0, 1, 100);
    }
    

    You’ll see this:

    color gradient

    Notice that the “vivid yellow” band is much more narrow than, for example, the green or blue bands. That’s why simply sampling every X values doesn’t generate a yellow color.

    The yellow color is around value 60, so you could modify your increment so it lands on 60. Drawing 12 rectangles with a width of 30 lets you land on the yellow:

    size(360,100);
    colorMode(HSB, 360, 100, 100);                                         
    noStroke();
    for (int i = 0; i < 360; i++)   
    {
        fill(i*30, 100, 100);
        rect(i*30, 0, 30, 100);
    }
    

    color gradient with yellow

    Or you could come up with the values you want ahead of time and put them in an array instead of using an even distribution:

    int[] hueValues = {0, 15, 30, 60, 90, 120, 150, 180, 210, 225, 240, 270, 300, 330, 360};
    
    size(360,100);
    colorMode(HSB, 360, 100, 100);                                         
    noStroke();
    for (int index = 0; index < hueValues.length; index++)   
    {
        float rectWidth = width/hueValues.length;
        fill(hueValues[index], 100, 100);
        rect(index*rectWidth, 0, rectWidth, height);
    }
    

    array color gradient

    Login or Signup to reply.
  2. I created a function that generates N colors (rainbow) and outputs a list of strings (Hex values). This is in C# but logic can be converted. In order to understand what’s going on I graphed the red, blue, and green values vs n. Doing that you’ll see the three graphs each are piecewise functions with points of interest at n=0, n=1/4, n=1/2 and n=3/4.

        List<string> GenerateRainbowPalette(int numColors)
        {
            var toRet = new List<SKColor>();
            var n = (float)numColors;
            for(var i = 0; i< numColors; i++)
            {
                int red = 255;
                int green = 0;
                int blue = 0;
                //red: (first quarter)
                if (i <= n / 4)
                {
                    red = 255;
                    green = (int)(255 / (n / 4) * i);
                    blue = 0;
                }
                else if (i <= n / 2)  //2nd quarter
                {
                    red = (int)((-255)/(n/4)*i + 255 * 2);
                    green = 255;
                    blue = 0;
                }
                else if (i <= (.75)*n)
                { // 3rd quarter
                    red = 0;
                    green = 255;
                    blue = (int)(255 / (n / 4) * i + (-255 * 2));
                }
                else if(i > (.75)*n)
                {
                    red = 0;
                    green = (int)(-255 * i / (n / 4) + (255 * 4));
                    blue = 255;
                }
    
                //generate hex string:
                var redHex = red.ToString("X2");
                var greenHex = green.ToString("X2");
                var blueHex = blue.ToString("X2");
    
                var color = $"#{redHex}{greenHex}{blueHex}";
            
             
                toRet.Add(color);
            }
            return toRet;
        }
    
    
       
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search