Color scaling function

后端 未结 8 1501
北荒
北荒 2020-12-08 11:40

I am trying to visualize some values on a form. They range from 0 to 200 and I would like the ones around 0 be green and turn bright red as they go to 200.

Basicall

8条回答
  •  北海茫月
    2020-12-08 12:09

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

提交回复
热议问题