2008-10-03 26 views
14

Estoy tratando de visualizar algunos valores en un formulario. Ellos van de 0 a 200 y me gustaría que los otros alrededor de 0, verde y vuelven de color rojo brillante a medida que avanzan a 200.Función de escala de color

Básicamente, la función debe devolver el color en función del valor introducido. Algunas ideas ?

Respuesta

17

Básicamente, el método general para la transición suave entre dos valores es la siguiente función:

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

Eso dado, se define una función que hace la transición para los tríos (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) 

Asumiendo que tiene los colores RGB para el s y e trillizos, puede utilizar la función transition3 tal cual. Sin embargo, pasar por el espacio de color HSV produce más transiciones "naturales". Por lo tanto, teniendo en cuenta las funciones de conversión (robados descaradamente desde el módulo colorsys Python y convertido a Pseudocódigo :):

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 

, puede hacer que el código de la siguiente manera:

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

+1; Iba a hacer una nueva pregunta sobre cómo mejorar un algoritmo de color que tengo para colorear un gráfico de barras en HTML/PHP ... SO sugirió esta pregunta como similar y su respuesta me ayudó a solucionar el problema sin tener que hacer la pregunta. ¡Gracias! – beggs

+2

+1, y un nombre mejor para su función 'transition' sería' lerp' ya que matemáticamente se trata de lo que está haciendo: http://en.wikipedia.org/wiki/Lerp_(computing) – Keith

7
red = (float)val/200 * 255; 

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

blue = 0; 

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

Esto hará que el punto medio (100) se vuelva verde: rgb (127, 127, 0). Querrá que su punto medio sea amarillo brillante o naranja. Ver: http://stackoverflow.com/questions/168838/color-scaling-function#168980 –

+1

Estoy de acuerdo con esto, que no se verá bien, sin embargo, soy un codificador y el punto medio no era parte de la especificación;) –

1

Mirando a través de this wikipedia article yo personalmente escoger un camino a través de un espacio de color, y el mapa de los valores en ese camino.

Pero esa es una función directa. Creo que podría adaptarse mejor a un selector de color de JavaScript que puede encontrar con un color rápido que le dará el maleficio, y puede almacenar el maleficio.

3

Elija un verde que te gusta (RGB1 = # 00FF00, por ejemplo) y un rojo que le gusta (RGB 2 = # FF0000, por ejemplo) y luego calcular el color como esto

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

Para un mejor controlable y efecto preciso, debe usar el espacio de color HSV. Con HSV, puede escalar fácilmente Hue, Saturación y/o Brillo separados entre sí. Luego, haces la transformación a RGB.

7

usted no dice en qué entorno que está haciendo esto. Si se puede trabajar con HSV colors, esto sería bastante fácil de hacer mediante el establecimiento de S = 100 y V = 100, y la determinación de H por:

H = 0.4 * value + 120 

Converting from HSV to RGB también es razonablemente fácil.

[EDIT] Nota: en contraste con algunas otras propuestas de solución, esto va a cambiar de color verde -> amarillo -> naranja -> rojo.

0

Si utiliza rampas lineales para Red y valores verdes como sugirió Peter Parker, el color para el valor 100 será básicamente puke green (127, 127, 0). Lo ideal es que sea naranja brillante o amarillo en ese punto medio. Por eso, se puede utilizar:

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

se extiende sobre el código de @ tzot ... también se puede establecer un punto medio entre los puntos inicial y final, que puede ser útil si se desea un "color de transición "¡!

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