В поисках N разных цветов RGB - PullRequest
10 голосов
/ 26 января 2010

Я пытаюсь графически отобразить график из N линий и пытаюсь найти способ динамически назначать разные цвета в зависимости от того, сколько у меня линий. Значения в RGB варьируются от 0 до 1. Я не могу использовать белый, потому что фон белый. Мне было легко для N <7: </p>

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

Это дает мне черный, синий, зеленый, голубой, красный, пурпурный, желтый. Но после этого он будет использовать белый, а затем цикл. Кто-нибудь знает хороший способ назначить значения RGB для индекса? У меня также есть значение непрозрачности для игры.

Ответы [ 3 ]

5 голосов
/ 26 января 2010

Мой предпочтительный метод для этого - найти n равномерно расположенных точек вдоль цветового круга.

Мы представляем цветовое колесо как диапазон значений от 0 до 360. Таким образом, мы будем использовать следующие значения: 360 / n * 0, 360 / n * 1, ..., 360 / n * (n - 1). При этом мы определили оттенок каждого из наших цветов. Мы можем описать каждый из этих цветов как цвета Hue-Saturation-Value (HSV), установив насыщенность на 1 и яркость на 1.

(Более высокая насыщенность означает, что цвет более «насыщенный»; более низкая насыщенность означает, что цвет ближе к серому. Более высокая яркость означает, что цвет «ярче»; более низкая яркость означает, что цвет «темнее».)

Теперь простой расчет дает нам значения 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)]
0 голосов
/ 26 января 2010
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):
      ...
0 голосов
/ 26 января 2010

Я написал этот код один раз, чтобы точно решить проблему, которую вы описываете (фон также был белым). Это та же идея, что и у вас, только обобщенная. Должно быть легко адаптироваться с OCaml к вашему языку.

Использование

Вам не нужно указывать функции, сколько цветов вам понадобится. Вызовите функцию с помощью кнопок 1, 2, ..., чтобы получить цвета номер 1, номер 2, ... Цвета из небольших чисел широко расставлены, последние цвета, конечно, становятся ближе и ближе друг к другу.

Код

lsl - это «логический сдвиг влево», lsr «логический сдвиг вправо», а ! просто означает «доступ к ссылке». В OCaml цвета RGB представлены одним целым числом, по одному байту на цвет.

let number_to_color n =
  let color = ref 0 in
  let number = ref n in
  for i = 0 to 7 do
    color := (!color lsl 1) +
      (if !number land 1 <> 0 then 1 else 0) +
      (if !number land 2 <> 0 then 256 else 0) +
      (if !number land 4 <> 0 then 65536 else 0);
    number := !number lsr 3
  done;
  !color
...