【问题标题】:Generate a n-color rainbow palette生成 n 色彩虹调色板
【发布时间】:2018-05-31 05:30:24
【问题描述】:

我正在尝试使用 (runnable code here) 生成具有 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 种彩虹色调色板,而是缺少一些颜色(例如鲜艳的黄色)。

是否有众所周知的算法可以生成生动的彩虹调色板?

【问题讨论】:

    标签: colors processing rgb color-palette hsb


    【解决方案1】:

    我创建了一个生成 N 种颜色(彩虹)并输出字符串列表(十六进制值)的函数。这是在 C# 中,但可以转换逻辑。为了了解发生了什么,我绘制了红色、蓝色和绿色值与 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;
        }
    
    
       
    

    【讨论】:

      【解决方案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);
      }
      

      【讨论】:

        猜你喜欢
        • 2011-03-12
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 2016-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多