Я пытаюсь графически отобразить график строк N, и я пытаюсь найти способ динамично присвоить разные цвета на основе того, сколько строк я имею. Значения в RGB колеблются от 0 до 1. Я не могу использовать белый, потому что фон является белым. Мне было легко для N <7:
r=(h&0x4)/4;
g=(h&0x2)/2;
b=h&0x1;
Это дает мне черный, синий, зеленый, голубой, красный, пурпурный, желтый. Но после этого это будет использовать белый и затем цикл. Кто-либо знает хороший способ присвоить значения RGB для индекса? У меня также есть значение непрозрачности для проигрывания с.
Мой предпочтительный метод для этого должен найти N
равномерно расположенные по цвету.
Мы представляем цветное колесо как диапазон значений от 0 до 360. Таким образом, значения, которые мы будем использовать 360 / N * 0
, 360 / N * 1
, ..., 360 / N * (N - 1)
. При этом мы определили оттенок каждого из наших цветов. Мы можем описать каждый из этих цветов как цвета HUE-насыщенности (HSV), устанавливая насыщенность до 1 и легкостью к 1.
(более высокое насыщение означает, что цвет более «богаты»; более низкая насыщенность означает, что цвет ближе к серому. Более высокая легкость означает, что цвет - «ярче»; нижняя легкость означает, что цвет «темнее».)
Теперь простой расчет дает нам значения RGB каждой из этих цветов.
http://en.wikipedia.org/wiki/hsl_and_hsv#conversion_from_hsv_to_rgb
Обратите внимание, что данные уравнения могут быть упрощены:
Примечание: это намеренно ужасно неэффективное реализация. Точка подачи этого примера в 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
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)]
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):
...
Я написал этот код однажды, чтобы решить именно ту проблему, которую вы описали (фон тоже был белым). Это та же идея, что и ваша, только обобщенная. Он должен быть легко адаптирован из 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