Funzione di ridimensionamento del colore
-
05-07-2019 - |
Domanda
Sto cercando di visualizzare alcuni valori in un modulo. Esse vanno da 0 a 200 e vorrei che quelle intorno a 0 fossero verdi e diventassero rosse mentre vanno a 200.
Fondamentalmente la funzione dovrebbe restituire il colore in base al valore immesso. Qualche idea?
Soluzione
Fondamentalmente, il metodo generale per una transizione graduale tra due valori è la seguente funzione:
function transition(value, maximum, start_point, end_point):
return start_point + (end_point - start_point)*value/maximum
Detto ciò, si definisce una funzione che esegue la transizione per terzine (RGB, HSV ecc.)
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)
Supponendo che tu abbia colori RGB per le terzine s e e , puoi usare la funzione transizione3 così com'è. Tuttavia, passare attraverso lo spazio colore HSV produce più "naturale" transizioni. Quindi, date le funzioni di conversione (rubate spudoratamente dal modulo colorsy di Python e convertite in pseudocodice :):
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
, puoi avere il codice come segue:
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))
Altri suggerimenti
Non dici in quale ambiente lo stai facendo. Se riesci a lavorare con colori HSV , sarebbe abbastanza facile farlo impostando S = 100 e V = 100 e determinando H con:
H = 0.4 * value + 120
Anche la conversione da HSV a RGB è ragionevolmente facile.
[EDIT] Nota: a differenza di alcune altre soluzioni proposte, questo cambierà colore verde - > giallo - > arancione - > rosso.
red = (float)val / 200 * 255;
green = (float)(200 - val) / 200 * 255;
blue = 0;
return red << 16 + green << 8 + blue;
Scegli un verde che ti piace (RGB1 = # 00FF00, ad esempio) e un rosso che ti piace (RGB2 = # FF0000, ad esempio) e quindi calcola il colore in questo modo
R = R1 * (200-i)/200 + R2 * i/200
G = G1 * (200-i)/200 + G2 * i/200
B = B1 * (200-i)/200 + B2 * i/200
Per un effetto controllabile e preciso, è necessario utilizzare lo spazio colore HSV. Con HSV, puoi facilmente ridimensionare tonalità, saturazione e / o luminosità separate l'una dall'altra. Quindi, esegui la trasformazione in RGB.
estendendosi al codice di @ tzot ... puoi anche impostare un punto intermedio tra i punti iniziale e finale, che può essere utile se vuoi un colore di transizione " ;!
//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)
Guardando questo articolo di Wikipedia sceglierei personalmente un percorso attraverso uno spazio colore e mappare i valori su quel percorso.
Ma questa è una funzione diretta. Penso che potresti essere più adatto a un selettore di colori javascript che puoi trovare con un colore rapido che ti darà l'esadecimale e puoi archiviare l'esagono.
Se si utilizzano rampe lineari per i valori Rosso e Verde, come suggerito da Peter Parker, il colore per il valore 100 sarà sostanzialmente puke green (127, 127, 0). Idealmente vuoi che sia un arancio o un giallo brillante in quel punto medio. Per questo, puoi usare:
Red = max(value / 100, 1) * 255
Green = (1 - max(value / 100, 1)) * 255
Blue = 0