Создайте радужную палитру из n цветов

Я пытаюсь создать радугу с 15 разными цветами с помощью (исполняемого кода здесь):

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

но он не создает богатую палитру из 15 радужных цветов, вместо этого некоторые цвета отсутствуют (например, ярко-желтый).

введите здесь описание изображения

Существует ли хорошо известный алгоритм для создания яркой цветовой палитры радуги?


person Basj    schedule 17.12.2017    source источник


Ответы (2)


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

Вы увидите это:

градиент цвета

Обратите внимание, что «ярко-желтая» полоса намного уже, чем, например, зеленая или синяя полосы. Вот почему простая выборка всех значений X не дает желтого цвета.

Желтый цвет соответствует значению 60, поэтому вы можете изменить приращение так, чтобы оно равнялось 60. Нарисовав 12 прямоугольников шириной 30, вы получите желтый цвет:

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

цветовой градиент с желтым

Или вы можете придумать нужные значения заранее и поместить их в массив вместо использования равномерного распределения:

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

градиент цвета массива

person Kevin Workman    schedule 18.12.2017

Я создал функцию, которая генерирует N цветов (радуга) и выводит список строк (шестнадцатеричные значения). Это на С#, но логику можно преобразовать. Чтобы понять, что происходит, я построил графики значений красного, синего и зеленого в зависимости от n. Сделав это, вы увидите три графика, каждый из которых представляет собой кусочную функцию с точками интереса при n=0, n=1/4, n=1/2 и 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;
    }


   
person Michael Gervasoni    schedule 15.10.2020