Color scaling function

无人久伴 提交于 2019-11-28 06:01:01

Basically, the general method for smooth transition between two values is the following function:

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

That given, you define a function that does the transition for triplets (RGB, HSV etc).

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)

Assuming you have RGB colours for the s and e triplets, you can use the transition3 function as-is. However, going through the HSV colour space produces more "natural" transitions. So, given the conversion functions (stolen shamelessly from the Python colorsys module and converted to pseudocode :):

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

, you can have code as following:

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))

You don't say in what environment you're doing this. If you can work with HSV colors, this would be pretty easy to do by setting S = 100 and V = 100, and determining H by:

H = 0.4 * value + 120

Converting from HSV to RGB is also reasonably easy.

[EDIT] Note: in contrast to some other proposed solutions, this will change color green -> yellow -> orange -> red.

Peter Parker
red = (float)val / 200 * 255;

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

blue = 0;

return red << 16 + green << 8 + blue;

Pick a green that you like (RGB1 = #00FF00, e.g.) and a Red that you like (RGB2 = #FF0000, e.g.) and then calculate the color like this

R = R1 * (200-i)/200 + R2 * i/200
G = G1 * (200-i)/200 + G2 * i/200
B = B1 * (200-i)/200 + B2 * i/200

For best controllable and accurate effect, you should use the HSV color space. With HSV, you can easily scale Hue, Saturation and/or Brightness seperate from each other. Then, you do the transformation to RGB.

extending upon @tzot's code... you can also set up a mid-point in between the start and end points, which can be useful if you want a "transition color"!

//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)

Looking through this wikipedia article I personally would pick a path through a color space, and map the values onto that path.

But that's a straight function. I think you might be better suited to a javascript color chooser you can find with a quick color that will give you the Hex, and you can store the Hex.

If you use linear ramps for Red and Green values as Peter Parker suggested, the color for value 100 will basically be puke green (127, 127, 0). You ideally want it to be a bright orange or yellow at that midpoint. For that, you can use:

Red = max(value / 100, 1) * 255
Green = (1 - max(value / 100, 1)) * 255
Blue = 0
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!