【问题标题】:Finding N Distinct RGB Colors寻找 N 种不同的 RGB 颜色
【发布时间】:2011-01-09 16:00:42
【问题描述】:

我正在尝试以图形方式显示 N 行的图形,并且我正在尝试找到一种方法来根据我拥有的行数动态分配不同的颜色。 RGB 中的值从 0 到 1。我不能使用白色,因为背景是白色的。我发现 N

r=(h&0x4)/4;
g=(h&0x2)/2;
b=h&0x1;

这给了我黑色、蓝色、绿色、青色、红色、品红色、黄色。但在那之后它将使用白色然后循环。有人知道为索引分配 RGB 值的好方法吗?我还有一个 opacity 值可以使用。

【问题讨论】:

  • 也许一个很好的答案要求是颜色尽可能远离彼此。 (如果您可以执行 0xF00、0x0F0 和 0x00F 之类的操作,您不想只选择 0x001、0x002 和 0x003)
  • 您并没有真正的不透明度值可玩 :) 在白色背景上,不透明度为 50% 的 0,0,0 与不透明度为 100% 的 127,127,127 相同。换句话说,不透明度并不独立于其他参数。

标签: colors rgb


【解决方案1】:

我的首选方法是在色轮上找到n 均匀分布的点。

我们将色轮表示为 0 到 360 之间的值范围。因此,我们将使用的值是 360 / n * 0360 / n * 1、...、360 / n * (n - 1)。在此过程中,我们定义了每种颜色的 hue。通过将饱和度设置为 1,将亮度设置为 1,我们可以将这些颜色中的每一种描述为色相饱和度 (HSV) 颜色。

(饱和度越高,颜色越“丰富”;饱和度越低,颜色越接近灰色。亮度越高,颜色“越亮”;亮度越低,颜色越“深”。)

现在,我们通过简单的计算得出每种颜色的 RGB 值。

http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_HSV_to_RGB

请注意,给出的方程式可以简化:

  • p = v * (1 - s) = 1 * (1 - 1) = 1 * 0 = 0
  • q = v * (1 - f * s) = 1 * (1 - f * 1) = 1 - f
  • t = v * (1 - (1 - f) * s) = 1 * (1 - (1 - f) * 1) = 1 - (1 - f) = 1 - 1 + f = f

Python 中的伪代码实现

注意:这是一个非常低效的实现。用 Python 给出这个例子的目的本质上是为了让我可以给出可执行的伪代码。

import math

def uniquecolors(n):
    """Compute a list of distinct colors, each of which is represented as an RGB 3-tuple."""
    hues = []
    # i is in the range 0, 1, ..., n - 1
    for i in range(n):
        hues.append(360.0 / i)

    hs = []
    for hue in hues:
        h = math.floor(hue / 60) % 6
        hs.append(h)

    fs = []
    for hue in hues:
        f = hue / 60 - math.floor(hue / 60)
        fs.append(f)

    rgbcolors = []
    for h, f in zip(hs, fs):
        v = 1
        p = 0
        q = 1 - f
        t = f
        if h == 0:
            color = v, t, p
        elif h == 1:
            color = q, v, p
        elif h == 2:
            color = p, v, t
        elif h == 3:
            color = p, q, v
        elif h == 4:
            color = t, p, v
        elif h == 5:
            color = v, p, q
        rgbcolors.append(color)

    return rgbcolors

Python 中的简洁实现

import math

v = 1.0
s = 1.0
p = 0.0
def rgbcolor(h, f):
    """Convert a color specified by h-value and f-value to an RGB
    three-tuple."""
    # q = 1 - f
    # t = f
    if h == 0:
        return v, f, p
    elif h == 1:
        return 1 - f, v, p
    elif h == 2:
        return p, v, f
    elif h == 3:
        return p, 1 - f, v
    elif h == 4:
        return f, p, v
    elif h == 5:
        return v, p, 1 - f

def uniquecolors(n):
    """Compute a list of distinct colors, ecah of which is
    represented as an RGB three-tuple"""
    hues = (360.0 / n * i for i in range(n))
    hs = (math.floor(hue / 60) % 6 for hue in hues)
    fs = (hue / 60 - math.floor(hue / 60) for hue in hues)
    return [rgbcolor(h, f) for h, f in zip(hs, fs)]

【讨论】:

  • 在前 20 种颜色之后,不利用饱和度和/或亮度不同于 1 的颜色变得有点浪费。
  • 完全正确。最好为 s = 1、v = 1 生成一组颜色,然后可能是 s = 0.5、v = 1 等等。据推测,可能有一种算法方法可以做到这一点,但必须进行检查以避免产生大量难以区分的近灰色或近黑色。
  • 如果 f = (h / 60 - math.floor(h / 60)) 因为 h 在 0 和 5 之间,所以 floor(h / 60) 不会总是为 0?如果这是真的,那么 f 介于 0 和 5/60 之间。对吗?
  • 很好,Suart - 我的意思是在那里写“hue”。谢谢!
  • 在 uniquecolors 的简洁实现中,hues 对象不应该是生成器,因为其他生成器将使用相同的迭代器,从而导致只有一半的预期颜色。将行更改为 hues = [...] 可以解决此问题。
【解决方案2】:
for r from 0 to 255 step (255*3/N):
  for g from 0 to 255 step (255*3/N):
    for b from 0 to 255 step (255*3/N):
      ...

【讨论】:

    【解决方案3】:

    我写了一次这段代码来解决你描述的问题(背景也是白色的)。和你的想法一样,只是泛泛而谈。从 OCaml 适应您的语言应该很容易。

    用法

    您不需要告诉函数您需要多少种颜色。用 1, 2, ... 调用函数得到颜色编号 1, 编号 2, ... 小数字的颜色相距很远,后面的颜色当然会越来越接近。

    代码

    lsl 是“逻辑左移”,lsr 是“逻辑右移”,! 仅表示“访问引用”。在 OCaml 中,RGB 颜色以单个整数表示,每种颜色一个字节。

    让 number_to_color n = 让颜色 = 参考 0 在 让 number = ref n in 对于 i = 0 到 7 做 颜色 := (!color lsl 1) + (如果 !number 土地 1 0 那么 1 否则 0)+ (如果 !number 土地 2 0 那么 256 否则 0)+ (如果 !number 土地 4 0 则 65536 否则为 0); 数字 := !number lsr 3 完毕; !颜色

    【讨论】:

      猜你喜欢
      • 2011-05-09
      • 2023-03-21
      • 2020-09-11
      • 2018-12-01
      • 2019-04-17
      • 2011-01-23
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多