Skip to content

Instantly share code, notes, and snippets.

@jdryg
Last active August 29, 2015 14:18
Show Gist options
  • Save jdryg/b083095d95fb5e4475d1 to your computer and use it in GitHub Desktop.
Save jdryg/b083095d95fb5e4475d1 to your computer and use it in GitHub Desktop.
Rainbow Gradient
using System;
using System.Drawing;
public class ColorUtil
{
public static Color GetRainbowColor(float percentage)
{
// The code below tries to mimick Matlab's color gradient. A naive implementation which
// linearly interpolates hue, ends up with a very large range mapped to greenish colors
// and we cannot distinguish different regions easily.
float h = 0.0f;
float s = 1.0f;
float v = 1.0f;
float p = Math.Max(Math.Min(percentage, 1.0f), 0.0f);
if (p < 0.125f)
{
h = 0.0f;
s = 1.0f;
v = 0.5f + 0.5f * p / 0.125f;
}
else if (p >= 0.125f && p < 0.375f)
{
h = 60.0f * (p - 0.125f) / (0.375f - 0.125f);
s = 1.0f;
v = 1.0f;
}
else if (p >= 0.375f && p < 0.5f)
{
h = 60.0f + 60.0f * (p - 0.375f) / (0.5f - 0.375f);
s = 1.0f - 0.5f * (p - 0.375f) / (0.5f - 0.375f);
v = 1.0f;
}
else if (p >= 0.5f && p < 0.625f)
{
h = 120.0f + 60.0f * (p - 0.5f) / (0.625f - 0.5f);
s = 0.5f + 0.5f * (p - 0.5f) / (0.625f - 0.5f);
v = 1.0f;
}
else if (p >= 0.625f && p < 0.875f)
{
h = 180.0f + 60.0f * (p - 0.625f) / (0.875f - 0.625f);
s = 1.0f;
v = 1.0f;
}
else // p >= 0.875f && p <= 1.0f
{
h = 240.0f;
s = 1.0f;
v = 1.0f - 0.5f * (p - 0.875f) / (1.0f - 0.875f);
}
return HSVColor(h, s, v);
}
public static Color HSVColor(double h, double S, double V)
{
double H = h;
while (H < 0) { H += 360; };
while (H >= 360) { H -= 360; };
double R, G, B;
if (V <= 0)
{
R = G = B = 0;
}
else if (S <= 0)
{
R = G = B = V;
}
else
{
double hf = H / 60.0;
int i = (int)Math.Floor(hf);
double f = hf - i;
double pv = V * (1 - S);
double qv = V * (1 - S * f);
double tv = V * (1 - S * (1 - f));
switch (i)
{
case 0:
R = V;
G = tv;
B = pv;
break;
case 1:
R = qv;
G = V;
B = pv;
break;
case 2:
R = pv;
G = V;
B = tv;
break;
case 3:
R = pv;
G = qv;
B = V;
break;
case 4:
R = tv;
G = pv;
B = V;
break;
case 5:
R = V;
G = pv;
B = qv;
break;
case 6:
R = V;
G = tv;
B = pv;
break;
case -1:
R = V;
G = pv;
B = qv;
break;
default:
R = G = B = V;
break;
}
}
return Color.FromArgb(255, Clamp((int)(R * 255.0), 0, 255), Clamp((int)(G * 255.0), 0, 255), Clamp((int)(B * 255.0), 0, 255));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment