Функция масштабирования цвета - PullRequest
14 голосов
/ 04 октября 2008

Я пытаюсь визуализировать некоторые значения в форме. Они варьируются от 0 до 200, и я хотел бы, чтобы те, которые около 0, были зелеными и стали ярко-красными, когда они приближаются к 200.

В основном функция должна возвращать цвет в зависимости от введенного значения. Есть идеи?

Ответы [ 8 ]

17 голосов
/ 04 октября 2008

По сути, общий метод плавного перехода между двумя значениями заключается в следующей функции:

function transition(value, maximum, start_point, end_point):
    return start_point + (end_point - start_point)*value/maximum

При этом вы определяете функцию, которая выполняет переход для триплетов (RGB, HSV и т. Д.).

function transition3(value, maximum, (s1, s2, s3), (e1, e2, e3)):
    r1= transition(value, maximum, s1, e1)
    r2= transition(value, maximum, s2, e2)
    r3= transition(value, maximum, s3, e3)
    return (r1, r2, r3)

Предполагая, что у вас есть цвета RGB для триплетов s и e , вы можете использовать функцию transition3 как есть. Однако прохождение цветового пространства HSV приводит к более «естественным» переходам. Итак, учитывая функции преобразования (бесстыдно похищенные из модуля Python colorsys и преобразованные в псевдокод:):

function rgb_to_hsv(r, g, b):
    maxc= max(r, g, b)
    minc= min(r, g, b)
    v= maxc
    if minc == maxc then return (0, 0, v)
    diff= maxc - minc
    s= diff / maxc
    rc= (maxc - r) / diff
    gc= (maxc - g) / diff
    bc= (maxc - b) / diff
    if r == maxc then
        h= bc - gc
    else if g == maxc then
        h= 2.0 + rc - bc
    else
        h = 4.0 + gc - rc
    h = (h / 6.0) % 1.0 //comment: this calculates only the fractional part of h/6
    return (h, s, v)

function hsv_to_rgb(h, s, v):
    if s == 0.0 then return (v, v, v)
    i= int(floor(h*6.0)) //comment: floor() should drop the fractional part
    f= (h*6.0) - i
    p= v*(1.0 - s)
    q= v*(1.0 - s*f)
    t= v*(1.0 - s*(1.0 - f))
    if i mod 6 == 0 then return v, t, p
    if i == 1 then return q, v, p
    if i == 2 then return p, v, t
    if i == 3 then return p, q, v
    if i == 4 then return t, p, v
    if i == 5 then return v, p, q
    //comment: 0 <= i <= 6, so we never come here

, вы можете иметь следующий код:

start_triplet= rgb_to_hsv(0, 255, 0) //comment: green converted to HSV
end_triplet= rgb_to_hsv(255, 0, 0) //comment: accordingly for red

maximum= 200

… //comment: value is defined somewhere here

rgb_triplet_to_display= hsv_to_rgb(transition3(value, maximum, start_triplet, end_triplet))
7 голосов
/ 04 октября 2008

Вы не говорите, в какой среде вы это делаете. Если вы можете работать с HSV цветами , это будет довольно легко сделать, установив S = 100 и V = 100 и определив H с помощью:

H = 0.4 * value + 120

Преобразование из HSV в RGB также достаточно просто.

[РЕДАКТИРОВАТЬ] Примечание: в отличие от некоторых других предлагаемых решений, это изменит цвет зеленый -> желтый -> оранжевый -> красный.

7 голосов
/ 04 октября 2008
red = (float)val / 200 * 255;

green = (float)(200 - val) / 200 * 255;

blue = 0;

return red << 16 + green << 8 + blue;
3 голосов
/ 04 октября 2008

Выберите зеленый, который вам нравится (RGB1 = # 00FF00, например), и красный, который вам нравится (RGB2 = # FF0000, например), и затем рассчитайте цвет следующим образом

R = R1 * (200-i)/200 + R2 * i/200
G = G1 * (200-i)/200 + G2 * i/200
B = B1 * (200-i)/200 + B2 * i/200
2 голосов
/ 18 февраля 2012

расширение кода @ tzot ... вы также можете установить среднюю точку между начальной и конечной точками, что может быть полезно, если вам нужен "цвет перехода"!

//comment: s = start_triplet, m = mid_triplet, e = end_triplet
function transition3midpoint = (value, maximum, s, m, e):
    mid = maximum / 2
    if value < mid
      return transition3(value, mid, s, m)
    else
      return transition3(value - mid, mid, m, e)
2 голосов
/ 04 октября 2008

Для лучшего контролируемого и точного эффекта, вы должны использовать цветовое пространство HSV. С HSV вы можете легко масштабировать оттенок, насыщенность и / или яркость отдельно друг от друга. Затем вы делаете преобразование в RGB.

1 голос
/ 04 октября 2008

Просмотр этой статьи в Википедии Я лично выбрал бы путь через цветовое пространство и отобразил значения на этот путь.

Но это прямая функция. Я думаю, что вы могли бы лучше подходить для выбора цвета javascript, который вы можете найти с помощью быстрого цвета, который даст вам Hex, и вы можете хранить Hex.

0 голосов
/ 04 октября 2008

Если вы используете линейные линейные изменения для значений красного и зеленого, как предложил Питер Паркер, цвет для значения 100 в основном будет рвотный зеленый (127, 127, 0). В идеале вы хотите, чтобы он был ярко-оранжевым или желтым в этой средней точке. Для этого вы можете использовать:

Red = max(value / 100, 1) * 255
Green = (1 - max(value / 100, 1)) * 255
Blue = 0
...