• 随机颜色的生成


    http://blog.csdn.net/hjh2005/article/details/8821052

    有些时候我们需要为一些对象附上随机的颜色,比如我们有这么一个需求,在一个chart里添加显示曲线,刚开始曲线的颜色默认都是黑色的很不好看,后来为了显示的美观我们想给添加的曲线随机的附上颜色,但是有一个要求,曲线的颜色不能太淡,比如不能是白色。因为我们的chart的背景颜色是白色的,如果曲线也是白色那曲线就会看不到了。

            我们首先想到的方法是如下:

    Color c(rand()%256,rand()%256,rand()%256);

            这样可以实现我们对随机颜色的要求,但是不满足我们不能为白色的要求,为了避免白色,我们在对这个颜色进行检查,如果r、g、b分量的值都超过230,表示颜色太淡重新随机,但是这样的方法总让人感觉不那么舒服。


            后来想到了在HSL颜色空间里做文章是否会更舒服呢?

            于是通过Wiki复习HSL颜色空间的知识。发现在HSL空间里如果L分量大于200,颜色看起来就比较淡了,所以我们可以随机生成小于200的数值作为L分量,再借助强大的Qt于是我们可以这样实现我们的需求:

            首先借助Qt的QColor生成一个颜色对象:

    QColor qc=QColor::fromHsl(rand()%360,rand()%256,rand()%200);

            这里要注意的是H分量的值域是0到359的。

            最后得到的颜色为:

    Color c(qc.red(),qc.green(),qc.blue());

            如果不用Qt的话,网上有很多HSL颜色空间转RGB颜色空间的代码和公式也可是替代上面用到的Qt。这样我们就省略了第一种方法里的循环,实现的方法看起来更加舒服了。


    有些时候我们可能会有这样的需求,比如我们想给一张地图上色,相邻的国家的颜色视觉区别要尽可能大,于是我们给的一种或几种颜色,要找到与这些颜色差别最大的颜色,这要怎么实现呢?下面是别人写的代码。我觉得还是有改进的空间的:

    1. static ColorType getUniqueColor(const std::vector<ColorType>& excludedColors)  
    2.     {  
    3.         unsigned int i,j,k;  
    4.         ColorType uniqueColor(0,0,0);  
    5.         //如果当前没有颜色  
    6.         if (excludedColors.size()==0)  
    7.         {  
    8.             return uniqueColor; //因为没有颜色所以随便返回一个颜色  
    9.         }  
    10.         //如果当前只有一个颜色  
    11.         if (excludedColors.size()==1)  
    12.         {  
    13.             int maxDist=-1;  
    14.             int red=excludedColors[0].mRed;  
    15.             int green=excludedColors[0].mGreen;  
    16.             int blue=excludedColors[0].mBlue;  
    17.               
    18.             for (i=0;i<256;i+=255)  
    19.             {  
    20.                 for (j=0;j<256;j+=255)  
    21.                 {  
    22.                     for (k=0;k<256;k+=255)  
    23.                     {  
    24.                         int dist=(i-red)*(i-red)+(j-green)*(j-green)+(k-blue)*(k-blue);  
    25.                         if (dist>maxDist)  
    26.                         {  
    27.                             maxDist=dist;  
    28.                             uniqueColor.mRed=i;  
    29.                             uniqueColor.mGreen=j;  
    30.                             uniqueColor.mBlue=k;  
    31.                         }  
    32.                     }  
    33.                 }  
    34.             }  
    35.              return uniqueColor;  
    36.         }  
    37.   
    38.         std::vector<unsigned int> badColors;  
    39.         badColors.reserve(excludedColors.size());  //预留空间  
    40.   
    41.         std::vector<ColorType>::const_iterator iter;  
    42.         for (iter=excludedColors.begin();iter!=excludedColors.end();iter++)  
    43.         {  
    44.             badColors.push_back((iter->mBlue<<16)+(iter->mGreen<<8)+iter->mRed);  
    45.         }  
    46.   
    47.         std::sort(badColors.begin(),badColors.end());  
    48.   
    49.         unsigned int duplicates=0;  
    50.         unsigned int next;  
    51.   
    52.         for (i=0,next=1;i<badColors.size()-duplicates;i++)  
    53.         {  
    54.             for (j = next; j < badColors.size(); j++)  
    55.             {  
    56.                 if (badColors[i] != badColors[j])  
    57.                 {  
    58.                     badColors[i + 1] = badColors[j];  
    59.                     next = j + 1;  
    60.                     break;  
    61.                 }  
    62.                 else  
    63.                 {  
    64.                     duplicates++;  
    65.                 }  
    66.             }  
    67.         }  
    68.         badColors.erase(badColors.begin() + (badColors.size() - duplicates), badColors.end());  
    69.   
    70.         std::vector<unsigned int>::iterator ulit = badColors.begin();  
    71.         unsigned int testColor;  
    72.         for (testColor = 0; testColor < 0xffffff; testColor++)  
    73.         {  
    74.             if (testColor == *ulit)  
    75.             {  
    76.                 ulit++;  
    77.             }  
    78.             else  
    79.             {  
    80.                 break;  
    81.             }  
    82.         }  
    83.   
    84.         if (testColor == 0x01000000)  // 如果搜遍了16.7百万的颜色都没找到的话,则返回无效的颜色  
    85.         {  
    86.             uniqueColor = ColorType();  
    87.         }  
    88.         else  
    89.         {  
    90.             uniqueColor.mBlue = (testColor&0xff0000)>>16;  
    91.             uniqueColor.mGreen = (testColor&0xff00)>>8;  
    92.             uniqueColor.mRed = testColor&0xff;  
    93.         }  
    94.   
    95.         return uniqueColor;  
    96.     }  

    ColorType是颜色类型,里面包含了三个分量。


    如果我们要同时获取多个不同的颜色呢?可以参考下面的代码:

    1. /** 
    2.      * 产生一个或多个唯一的颜色 
    3.      * @param count 要产生的颜色的个数 
    4.      * @param colors 用于保存生成颜色的向量 
    5.      * @param excludeColors 要排除的颜色 
    6.      * @return 产生的颜色的个数 
    7.      */  
    8.    static unsigned int getUniqueColors(unsigned int count, std::vector<ColorType>& colors,  
    9.         const std::vector<ColorType>& excludeColors)  
    10.     {  
    11.         unsigned int i, j, k, l;  
    12.         unsigned int numUnique = 0;  
    13.         double slValues[] = {0.0, 1.0, 0.5, 0.8, 0.3, 0.6, 0.9, 0.2, 0.7, 0.4, 0.1};  
    14.         ColorType baseColors[] =  
    15.         {  
    16.             ColorType(0,0,255),  
    17.             ColorType(0,255,0),  
    18.             ColorType(255,0,0),  
    19.             ColorType(0,255,255),  
    20.             ColorType(255,255,0),  
    21.             ColorType(255,0,255),  
    22.             ColorType(255,255,255)  
    23.         };  
    24.   
    25.         for (i = 0; i < sizeof(slValues) / sizeof(slValues[0]); i++)  
    26.         {  
    27.             for (j = 0; j < sizeof(slValues) / sizeof(slValues[0]); j++)  
    28.             {  
    29.                 for (k = 0; k < sizeof(baseColors) / sizeof(baseColors[0]); k++)  
    30.                 {  
    31.                     int newColor[3];  
    32.                     int maxValue;  
    33.   
    34.                     newColor[0] = (int) (baseColors[k].mRed * slValues[j] + 0.5);  
    35.                     newColor[1] = (int) (baseColors[k].mGreen * slValues[j] + 0.5);  
    36.                     newColor[2] = (int) (baseColors[k].mBlue * slValues[j] + 0.5);  
    37.   
    38.                     maxValue = 0;  
    39.                     for (l = 0; l < 3; l++)  
    40.                     {  
    41.                         if (newColor[l] > maxValue)  
    42.                         {  
    43.                             maxValue = newColor[l];  
    44.                         }  
    45.                     }  
    46.   
    47.                     maxValue = (int) (maxValue * slValues[i] + 0.5);  
    48.                     for (l = 0; l < 3; l++)  
    49.                     {  
    50.                         if (newColor[l] < maxValue)  
    51.                         {  
    52.                             newColor[l] = maxValue;  
    53.                         }  
    54.                     }  
    55.   
    56.                     ColorType colorToInsert;  
    57.                     colorToInsert.mRed = newColor[0];  
    58.                     colorToInsert.mGreen = newColor[1];  
    59.                     colorToInsert.mBlue = newColor[2];  
    60.   
    61.                     for (l=0; l<excludeColors.size(); l++)  
    62.                     {  
    63.                         if (excludeColors[l].mRed == colorToInsert.mRed &&  
    64.                             excludeColors[l].mGreen == colorToInsert.mGreen &&  
    65.                             excludeColors[l].mBlue == colorToInsert.mBlue)  
    66.                         {  
    67.                             break;  
    68.                         }  
    69.                     }  
    70.                     if (l == excludeColors.size())  
    71.                     {  
    72.                         for (l = 0; l < colors.size(); l++)  
    73.                         {  
    74.                             if (colors[l].mRed == colorToInsert.mRed &&  
    75.                                 colors[l].mGreen == colorToInsert.mGreen &&  
    76.                                 colors[l].mBlue == colorToInsert.mBlue)  
    77.                             {  
    78.                                 break;  
    79.                             }  
    80.                         }  
    81.                         if (l == colors.size())  
    82.                         {  
    83.                             colors.push_back (colorToInsert);  
    84.                             ++numUnique;  
    85.                             if (colors.size() == count)  
    86.                             {  
    87.                                 return numUnique;  
    88.                             }  
    89.                         }  
    90.                     }  
    91.                 }  
    92.             }  
    93.         }  
    94.         return numUnique;  
    95.     }  
    Keep it simple!
    作者:N3verL4nd
    知识共享,欢迎转载。
  • 相关阅读:
    Vue 计算属性(四)
    Vue 方法与事件(三)
    Vue 基本指令使用(二)
    Vue 项目开发环境搭建(一)
    SpringBoot 整合 Dubbo
    Nginx 中 include 指令使用
    Nginx 中 root 和 alias 的使用区别
    JS动态修改网站图标以及标题
    vue中使用轮播图插件carousel,克隆的图片点击事件无效的解决办法
    根据 url + fileName下载文件,并更改文件名
  • 原文地址:https://www.cnblogs.com/lgh1992314/p/5834797.html
Copyright © 2020-2023  润新知