Generate colors between red and green for a power meter?
I'm writing a Java game and I want to implement a power meter for how hard you are going to shoot something.
I need to write a function that takes a int between 0 - 100, and based on how high that number is, it will return a color between Green (0 on the power scale) and Red (100 on the power scale).
Similar to how volume controls work:
What operation do I need to do on the Red, Green, and Blue components of a color to generate the colors between Green and Red?
So, I could run say, getColor(80)
and it will return an orangish color (its values in R, G, B) or getColor(10)
which will return a more Green/Yellow RGB value.
I know I need to increase components of the R, G, B values for a new color, but I don't know specifically what goes up or down as the colors shift from Green-Red.
Progress:
I ended up using HSV/HSB color space because I liked the gradiant better (no dark browns in the middle).
The function I used was:
public Color getColor(double power)
{
double H = power * 0.4; // Hue (note 0.4 = Green, see huge chart below)
double S = 0.9; // Saturation
double B = 0.9; // Brightness
return Color.getHSBColor((float)H, (float)S, (float)B);
}
Where "power" is a number between 0.0 and 1.0. 0.0 will return a bright red, 1.0 will return a bright green.
Java Hue Chart:
This should work - just linearly scale the red and green values. Assuming your max red/green/blue value is 255
, and n
is in range 0 .. 100
R = (255 * n) / 100
G = (255 * (100 - n)) / 100
B = 0
(Amended for integer maths, tip of the hat to Ferrucio)
Another way to do would be to use a HSV colour model, and cycle the hue from 0 degrees
(red) to 120 degrees
(green) with whatever saturation and value suited you. This should give a more pleasing gradient.
Here's a demonstration of each technique - top gradient uses RGB, bottom uses HSV:
Off the top of my head, here is the green-red hue transition in HSV space, translated to RGB:
blue = 0.0
if 0<=power<0.5: #first, green stays at 100%, red raises to 100%
green = 1.0
red = 2 * power
if 0.5<=power<=1: #then red stays at 100%, green decays
red = 1.0
green = 1.0 - 2 * (power-0.5)
The red, green, blue values in the above example are percentages, you'd probably want to multiply them by 255 to get the most used 0-255 range.
Short Copy'n'Paste answer...
On Java Std:
int getTrafficlightColor(double value){
return java.awt.Color.HSBtoRGB((float)value/3f, 1f, 1f);
}
On Android:
int getTrafficlightColor(double value){
return android.graphics.Color.HSVToColor(new float[]{(float)value*120f,1f,1f});
}
note: value is a number between 0 and 1 indicating the red-to-green condition.
If you want an green-yellow-red representation like the accepted answer suggests then take a look at this.
http://jsfiddle.net/0awncw5u/2/
function percentToRGB(percent) {
if (percent === 100) {
percent = 99
}
var r, g, b;
if (percent < 50) {
// green to yellow
r = Math.floor(255 * (percent / 50));
g = 255;
} else {
// yellow to red
r = 255;
g = Math.floor(255 * ((50 - percent % 50) / 50));
}
b = 0;
return "rgb(" + r + "," + g + "," + b + ")";
}
function render(i) {
var item = "<li style='background-color:" + percentToRGB(i) + "'>" + i + "</li>";
$("ul").append(item);
}
function repeat(fn, times) {
for (var i = 0; i < times; i++) fn(i);
}
repeat(render, 100);
li {
font-size:8px;
height:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<ul></ul>