C# Color hues for different values
I would like some advice on how to accomplish the following within C#. I would like to plot a "color", the exact color will be determined by a property value, for the sake of this example let's assume it's a percentage.
Ideally I'd like the user to specify five colors.
Negative MAX
Negative MIN
Even
Positive MIN
Positive MAX
The user is only specifying colors for each level, not 开发者_开发技巧the value which determines Min and Max.
Using this data, I would like to be able to calculate a color based on a percentage. i.e. 57% would result in a color hue in between Positive MIN and Positive MAX. Any help or advice for this is appreciated.
To interpolate between two colors you just interpolate each color channel
Color color1 = Color.Red;
Color color2 = Color.Green;
double fraction = 0.3;
Color color3 = Color.FromArgb(
(int)(color1.R * fraction + color2.R * (1 - fraction)),
(int)(color1.G * fraction + color2.G * (1 - fraction)),
(int)(color1.B * fraction + color2.B * (1 - fraction)));
To interpolate along your scale you need to decide what exact percentage values your "steps" have and project your target value that a fraction between two of those color steps.
Using the function copied from here, you can convert the hues back into RGB colors. This function assumes has all inputs and outputs in on a 0..1 scale, so you'll need to divide by color.GetHue() by 255. Below the function is some sample code using a set of percentages; implement DisplayColor in the UI of your choice to see the results.
public static void HSVToRGB(double H, double S, double V, out double R, out double G, out double B)
{
if (H == 1.0)
{
H = 0.0;
}
double step = 1.0/6.0;
double vh = H/step;
int i = (int) System.Math.Floor(vh);
double f = vh - i;
double p = V*(1.0 - S);
double q = V*(1.0 - (S*f));
double t = V*(1.0 - (S*(1.0 - f)));
switch (i)
{
case 0:
{
R = V;
G = t;
B = p;
break;
}
case 1:
{
R = q;
G = V;
B = p;
break;
}
case 2:
{
R = p;
G = V;
B = t;
break;
}
case 3:
{
R = p;
G = q;
B = V;
break;
}
case 4:
{
R = t;
G = p;
B = V;
break;
}
case 5:
{
R = V;
G = p;
B = q;
break;
}
default:
{
// not possible - if we get here it is an internal error
throw new ArgumentException();
}
}
}
Color min = Color.Blue;
Color max = Color.Green;
float minHue = min.GetHue() / 255;
float maxHue = max.GetHue() / 255;
float scale = maxHue - minHue;
float[] percents = new float[] { .05F, .15F, .40F, .70F, .85F, .95F };
foreach (var pct in percents) {
float curHue = minHue + (scale * pct);
double r, g, b;
HSVToRGB(curHue, 1.0, 1.0, out r, out g, out b);
Color curColor = Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255));
DisplayColor(curColor);
}
精彩评论