生成唯一的颜色

18

我想将一些数据绘制到一个纹理中:有很多个矩形,并不是按顺序创建的,它们可能大小各异(类似于内存堆)。每个数据项都是一个小矩形,我想要能够区分它们,所以我想让它们每个都具有唯一的颜色。

现在,我可以使用rand()生成RGB值,希望它们都不同,但我怀疑在RGB空间中得到好的分布。除此之外,是否有更好的方法呢?例如,在它们(几乎)重复之前循环使用不同的颜色的好方法是什么?

这些颜色不必与项中的任何数据匹配,我只想能够查看许多值并看到它们的不同之处,因为它们相邻。

我可以想出一些东西,但我认为这是一个有趣的问题。 :)


这是真的!这是一个非常有趣的问题 :-) - dfa
请查看以下链接:https://dev59.com/pHRB5IYBdhLWcg3w6bUD#4382138。 - Ohad Schneider
6个回答

13
使用RGB颜色模型并不是获得良好颜色混合的好方法。最好使用另一种颜色模型来生成您的颜色,然后从该颜色模型转换为RGB。
我建议您使用HSV或HSL颜色模型,特别是如果您想要变化色相
如果您想要X个不同的颜色值,请将它们从0到360变化,步长为360除以X。

1
0、360(相同颜色)、180、300、390、102、162、213、258、298(基本上又是300)、334、367(基本上又是360第三次)。 - Tatarize

4

你的样本空间是什么...我们要讨论多少项。

你可以从中构建RGB三元数组

for(int r = 0; r < 255; r = r+16)
   for(int g = 0; g < 255; g = g+16)
      for(int b = 0; b < 255; b = b+16)
           // take r, g, b and add it to a list

然后随机排列您的列表并遍历它。 这将给您提供16 ^ 3(4096)种不同的颜色,然后才会出现重复的颜色。

这与 rand(0,16) << 20 | rand(0,16) << 12 | rand(0,16) << 4 完全相同。它是一个随机颜色,介于 #000 和 #FFF 之间的 12 位颜色,并检查是否有重复。例如,您的 #0A0 和 #090,特别是在绿色区分方面,看起来会非常相似。 - Tatarize

4
一般来说,RGB不是做这些事情的最佳颜色空间,因为从感知上讲,它是非线性的。这意味着在RGB三元组之间移动相等的距离对我们的眼睛来说并不完全相同。
我可能会在L*c*h*空间(参见)或HSL空间中工作,并仅在色调上生成均匀间距。这些空间的设计目的是近似感知线性的。

2
即使在HSL中,色调的正常间距也不是感知线性的 - Phrogz
1
HSL是从RGB直接进行数学转换,而不考虑特定的色调。这些空间并不是设计成线性的。LCH是LAB的修改版,实际上需要基于色调的拉伸来更好地适应人眼。 - Tatarize

2
请翻译以下内容:

搜索“delta e cie 2000”,颜色差异公式有助于确定两种颜色之间的视觉距离(在显示器上;颜料有不同的公式)。它在Lab空间中操作颜色(向西蒙致敬),但应用了感知差异的计算。

我们发现,大约1.5左右的数字足以确保颜色在视觉上是不同的(即使它们彼此相邻,你也可以看出它们之间的区别),但如果您想要可识别的颜色(您可以在图例中找到任何颜色),则需要增加这个数字。

至于创建一组颜色... 我可能会从Lab空间的某个角落开始,使用足够大的步长在周围走动(注意:它不是线性的,因此步长可能需要自适应),然后随机排列列表。


0

这与涂色地图的四色问题非常相似,这可能会为您带来一些有趣的解决方案:

四色定理


2
它实际上与四色问题并不那么相似。Nick使用尽可能多的颜色,而着色问题则试图最小化所需的颜色数量.... - simon
实际上,这与四色问题无关,其中只需要4种颜色,并且它们仅用作“标签”。在这里,他关心所选颜色的光学特性(相似性)。 - Hejazzman
1
我不同意,我认为这里的四色问题是有价值的。这个问题是通过使用颜色来区分在二维平面上排列的物品。四色问题证明了你可以只使用4种对比鲜明的颜色来解决这个问题。 - Mark Pim
我确实考虑过四色问题,但我不按已知顺序创建矩形。我想我可以重新分配颜色,并且只是在一行中交替使用它们:二色问题!但我认为重新分配颜色会让用户感到困惑。这会让你觉得现有数据已经改变了,但实际上并没有。 - Nick
1
Lazarus;我想表达的观点是,四色问题之所以难是因为你必须重复使用颜色。尼克可能已经拥有了他想要的颜色,只需要一种生成可区分颜色的方法。这是一个非常不同的问题(不完全无关,但非常不同)。 - simon
显示剩余4条评论

0

如果你只需要一组感知上不同的颜色(而不是生成它们的算法),我在我的网站上创建了一个免费工具,可以做到这一点:
http://phrogz.net/css/distinct-colors.html

该工具不仅使用RGB或HSV空间中的均匀间距(这些间距与人类感知不均匀分布),还允许您在HSV空间中生成值网格,然后使用CMC(I:c)标准来计算颜色距离,以排除感知上过于接近的颜色。(第二个选项卡上的“阈值”滑块允许您控制颜色的视觉差异程度,并实时显示结果。)

最终,您可以按各种标准对生成的颜色列表进行排序,然后平均“洗牌”该列表,以便在列表中保证相邻的值具有视觉上不同的特征。(我建议将“交错”值设置为约5。)

截至目前,该工具在Chrome、Safari和(通过一个shim)Firefox上运行良好;IE9不支持HTML5范围输入滑块,而UI在交互式探索中广泛使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接