15

我正在尝试在表单上可视化一些值。它们的范围从 0 到 200,我希望 0 附近的那些是绿色的,当它们达到 200 时变成鲜红色。

基本上,该函数应根据输入的值返回颜色。有任何想法吗 ?

4

8 回答 8

17

基本上,两个值之间平滑过渡的一般方法是以下函数:

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)

假设您有se三元组的 RGB 颜色,您可以按原样使用 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))
于 2008-10-03T21:26:19.713 回答
7
red = (float)val / 200 * 255;

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

blue = 0;

return red << 16 + green << 8 + blue;
于 2008-10-03T20:51:46.210 回答
7

你没有说你在什么环境下做这个。如果您可以使用HSV 颜色,这将很容易通过设置 S = 100 和 V = 100 并通过以下方式确定 H:

H = 0.4 * value + 120

从 HSV 转换为 RGB也相当容易。

[编辑] 注意:与其他一些提议的解决方案相比,这将改变颜色绿色 -> 黄色 -> 橙色 -> 红色。

于 2008-10-03T20:57:50.193 回答
3

选择一个你喜欢的绿色(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
于 2008-10-03T20:55:11.570 回答
2

为了获得最佳可控和准确的效果,您应该使用 HSV 颜色空间。使用 HSV,您可以轻松地将色相、饱和度和/或亮度彼此分开。然后,您对 RGB 进行转换。

于 2008-10-03T20:57:34.077 回答
2

扩展@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)
于 2012-02-18T03:31:33.040 回答
1

浏览这篇维基百科文章,我个人会选择一条穿过色彩空间的路径,并将值映射到该路径上。

但这是一个直接的功能。我认为您可能更适合javascript颜色选择器,您可以找到一种快速颜色,可以为您提供十六进制,并且您可以存储十六进制。

于 2008-10-03T20:53:06.753 回答
1

如果您按照 Peter Parker 的建议对红色和绿色值使用线性渐变,则值 100 的颜色基本上是绿色(127、127、0)。理想情况下,您希望它在该中点呈亮橙色或黄色。为此,您可以使用:

Red = max(value / 100, 1) * 255
Green = (1 - max(value / 100, 1)) * 255
Blue = 0
于 2008-10-03T21:27:57.697 回答