Jeśli idziesz z jasnym kolorem na jasny kolor jako wartości hex zasugerować, to może chcesz interpolacji w HSV space zamiast przestrzeni RGB. Przestrzeń HSV jest zbliżona do tego, jak myślimy o kolorze - odcień, nasycenie i wartość. Przestrzeń RGB przybliża sposób działania wrażliwych na światło komórek w naszych oczach.
Górny gradient to liniowa interpolacja RGB od FF0000 do 00FF00. Jego średnia wartość to 7f7f00, błotnisty brąz.
Środkowy gradient to interpolacja liniowa w przestrzeni HSV. Ponieważ zarówno FF0000, jak i 00FF00 są w pełni nasycone i mają tę samą wartość (jasność), interpolacja zachowuje tę samą jasność i nasycenie w całym tekście, więc wartość środkowa jest jasnożółta ffff00.
Trzecią alternatywą byłaby rotacja wektora w przestrzeni RGB, co oznaczałoby, że wartość środkowa to B4B400, (B4 hex = 180 dec = 255/sqrt (2)), która znajduje się gdzieś pomiędzy dwoma efektami. Odbywa się to poprzez obliczenie wielkości każdego punktu końcowego, a następnie skalowanie wyniku interpolacji liniowej RGB, tak aby była ona tej samej wielkości, skutecznie przesuwając wektor w łuku w płaszczyźnie dwóch kolorów i punktu początkowego. Ponieważ tak naprawdę nie ważymy różnych kolorów równomiernie dla jasności, ani nie widzimy liniowo, nie jest to dokładne, ale ma dość równomierną intensywność w całym cyklu, podczas gdy HSV jest nieco lżejsze w środku, ponieważ ma dwie wartości na 100%.
usuwa martwy link Imageshack
W Javie, gdzie masz wsparcie HSB algorytm jest prosty - dostać HSB wartości końcowych, liniowa interpolacja je podobnie jak w innych odpowiedzi RGB, a następnie konwertować utworzyć kolor z h, s, V wartości:
static Color hsvInterpolate (float mix, Color c0, Color c1) {
float[] hsv0 = new float[3];
float[] hsv1 = new float[3];
float alt = 1.0f - mix;
Color.RGBtoHSB(c0.getRed(), c0.getGreen(), c0.getBlue(), hsv0);
Color.RGBtoHSB(c1.getRed(), c1.getGreen(), c1.getBlue(), hsv1);
float h = mix * hsv0 [ 0 ] + alt * hsv1 [ 0 ];
float s = mix * hsv0 [ 1 ] + alt * hsv1 [ 1 ];
float v = mix * hsv0 [ 2 ] + alt * hsv1 [ 2 ];
return Color.getHSBColor (h, s, v);
}
nie wierzę, C# ma konwersji wbudowane, więc kod nie jest dużo używać naprawdę.
static Color vectorInterpolate (float mix, Color c0, Color c1) {
float alt = 1.0f - mix;
double x0 = c0.getRed();
double y0 = c0.getGreen();
double z0 = c0.getBlue();
double x1 = c1.getRed();
double y1 = c1.getGreen();
double z1 = c1.getBlue();
double mag0 = sqrt(x0*x0 + y0*y0 + z0*z0);
double mag1 = sqrt(x1*x1 + y1*y1 + z1*z1);
double x = mix * x0 + alt * x1;
double y = mix * y0 + alt * y1;
double z = mix * z0 + alt * z1;
double mag = mix * mag0 + alt * mag1;
double scale = mag/sqrt(x*x + y*y + z*z);
return new Color (
clamp (x * scale),
clamp (y * scale),
clamp (z * scale));
}
static int clamp (double value) {
int x = (int) round (value);
if (x > 255) return 255;
if (x < 0) return 0;
return x;
}
Prawdopodobnie chcesz znaleźć przecięcie wektora z krawędzi sześcianu RGB zamiast po prostu go zaciskania, ale w tym przypadku nie ma znaczenia, tak czy inaczej.
jako dodatek, to również warto zastanowić HSY przestrzeń, która jest bliżej postrzeganej jasności, co ilustruje Dave Green's cube helix interpolacji kolorów.
Twoje obie poprawne, co jest do bani. Chciałbym dać odpowiedź obu wam. –
Cóż, Scott dokonał dobrego wyboru, ponieważ Chad Birch jest znacznie łatwiejszy niż odpowiedź Pete'a Kirkhama. –