为功率计生成红色和绿色之间的颜色?

发布于 2024-07-09 22:52:33 字数 985 浏览 6 评论 0原文

我正在编写一个 Java 游戏,我想实现一个功率计来测量您射击某物的力度。

我需要编写一个函数,它接受 0 - 100 之间的整数,并根据该数字的高低,它将返回绿色(功率刻度上的 0)和红色(功率刻度上的 100)之间的颜色。

与音量控制的工作原理类似:
volume control

我需要对颜色的红、绿、蓝分量进行什么操作才能生成之间的颜色绿色和红色?

因此,我可以运行 getColor(80) ,它将返回橙色(其值在 R、G、B 中)或 getColor(10) 它将返回更多绿色/黄色 RGB 值。

我知道我需要增加新颜色的 R、G、B 值的分量,但我不知道当颜色从绿红转变时具体会上升或下降。


进展:

我最终使用了 HSV/HSB 颜色空间,因为我更喜欢渐变(中间没有深棕色)。

我使用的函数是:

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);
}

其中“power”是 0.0 到 1.0 之间的数字。 0.0 将返回亮红色,1.0 将返回亮绿色。

Java 色调图表:
Java 色调图表

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:
volume control

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:
Java Hue Chart

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

凯凯我们等你回来 2024-07-16 22:52:33

这应该可行 - 只需线性缩放红色和绿色值。 假设您的最大红/绿/蓝值为 255,并且 n 的范围为 0 .. 100

R = (255 * n) / 100
G = (255 * (100 - n)) / 100 
B = 0

(针对整数数学进行了修改,向 Ferrucio 致敬)

另一种方法是使用 HSV 颜色模型,并使用适合您的饱和度和值将色调从 0 度(红色)到 120 度(绿色)循环。 这应该会产生更令人满意的渐变。

以下是每种技术的演示 - 顶部渐变使用 RGB,底部使用 HSV:

http://i38.tinypic.com/29o0q4k。 jpg

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:

http://i38.tinypic.com/29o0q4k.jpg

故事与诗 2024-07-16 22:52:33

在我的脑海中,这是 HSV 空间中的绿-红色调过渡,转换为 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)

上例中的红、绿、蓝值是百分比,您可能需要将它们乘以 255 以获得最常用的0-255范围。

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.

晌融 2024-07-16 22:52:33

简短的复制粘贴答案...

在 Java Std 上:

int getTrafficlightColor(double value){
    return java.awt.Color.HSBtoRGB((float)value/3f, 1f, 1f);
}

在 Android 上:

int getTrafficlightColor(double value){
    return android.graphics.Color.HSVToColor(new float[]{(float)value*120f,1f,1f});
}

注意:值是 0 到 1 之间的数字,表示红到绿的状态。

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.

栖迟 2024-07-16 22:52:33

如果您想要像接受的答案所建议的那样的绿-黄-红表示,那么请看一下这个。

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>

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>

孤凫 2024-07-16 22:52:33

在绿色和红色之间线性插值几乎应该可以工作,除了中间会有浑浊的棕色。

最灵活、最好看的解决方案是在某个位置拥有一个具有您想要的确切色带的图像文件。 然后查找其中的像素值。 这具有灵活性,您可以将渐变调整到恰到好处

如果您仍然想从代码中执行此操作,那么最好在左侧的绿色和黄色之间以及右侧的黄色和红色之间进行插值。 在RGB空间中,绿色为(R=0,G=255,B=0),黄色为(R=255,G=255,B=0),红色为(R=255,G=0,B=0) ) - 假设每个颜色分量的范围为 0 到 255。

Linearly interpolating between green and red almost should work, except that in the middle there will be muddy brown color.

The most flexible and best looking solution is to have an image file somewhere that has the exact color ramp you want. And then lookup the pixel value in there. This has the flexibility that you can tweak the gradient to be just right.

If you still want to do it from code, then it's probably best to interpolate between green and yellow colors in the left side, and between yellow and red on the right side. In RGB space, green is (R=0, G=255, B=0), yellow is (R=255, G=255, B=0), red is (R=255, G=0, B=0) - this is assuming each color component goes from 0 to 255.

你与清晨阳光 2024-07-16 22:52:33

我制作了一个小函数,它为您提供百分比值的 rgb 整数值:

private int getGreenToRedGradientByValue(int currentValue, int maxValue)
{
    int r = ( (255 * currentValue) / maxValue );
    int g = ( 255 * (maxValue-currentValue) ) / maxValue;
    int b = 0;
    return ((r&0x0ff)<<16)|((g&0x0ff)<<8)|(b&0x0ff);
}

因此,如果您的 currentValue 是 50 并且 maxValue 是 100,则此函数将返回您需要的颜色,因此如果您使用百分比值循环此函数,你的颜色值将从绿色变为红色。 抱歉解释不好

I made a small function wich gives you the rgb integer value for a percentage value:

private int getGreenToRedGradientByValue(int currentValue, int maxValue)
{
    int r = ( (255 * currentValue) / maxValue );
    int g = ( 255 * (maxValue-currentValue) ) / maxValue;
    int b = 0;
    return ((r&0x0ff)<<16)|((g&0x0ff)<<8)|(b&0x0ff);
}

So if your currentValue is 50 and your maxValue is 100, this function will return the color that you need, so if you loop this function with a percentage value, your color value will go from green to red. Sorry for the bad explanation

拔了角的鹿 2024-07-16 22:52:33

我想说你想要 HSV 空间中的线段(中心有一个稍微太亮的黄色)和 RGB 空间中的线段(中心有一个难看的棕色)之间的东西。 我会使用这个,其中 power = 0 将给出绿色,power = 50 将给出略暗的黄色,而 power = 100 将给出红色的。

blue = 0;
green = 255 * sqrt( cos ( power * PI / 200 ));
red = 255 * sqrt( sin ( power * PI / 200 )); 

I'd say you want something in between a line segment in the HSV space (which has a slightly-too-bright yellow in the centre) and a line segment in the RGB space (which has an ugly brown in the centre). I would use this, where power = 0 will give green, power = 50 will give a slightly dull yellow, and power = 100 will give red.

blue = 0;
green = 255 * sqrt( cos ( power * PI / 200 ));
red = 255 * sqrt( sin ( power * PI / 200 )); 
俏︾媚 2024-07-16 22:52:33

接受的答案甚至没有真正回答问题...

C++

这是我的引擎中的一个简单的 C++ 代码段,它在三种任意颜色之间线性有效地插值:

const MATH::FLOAT4 color1(0.0f, 1.0f, 0.0f, 1.0f);  // Green
const MATH::FLOAT4 color2(1.0f, 1.0f, 0.0f, 1.0f);  // Yellow
const MATH::FLOAT4 color3(1.0f, 0.0f, 0.0f, 1.0f);  // Red

MATH::FLOAT4 get_interpolated_color(float interpolation_factor)
{
    const float factor_color1 = std::max(interpolation_factor - 0.5f, 0.0f);
    const float factor_color2 = 0.5f - fabs(0.5f - interpolation_factor);
    const float factor_color3 = std::max(0.5f - interpolation_factor, 0.0f);

    MATH::FLOAT4 color;

    color.x = (color1.x * factor_color1 +
               color2.x * factor_color2 +
               color3.x * factor_color3) * 2.0f;

    color.y = (color1.y * factor_color1 +
               color2.y * factor_color2 +
               color3.y * factor_color3) * 2.0f;

    color.z = (color1.z * factor_color1 +
               color2.z * factor_color2 +
               color3.z * factor_color3) * 2.0f;

    color.w = 1.0f;

    return(color);
}

假设 interpolation_factor 在范围内0.0 ... 1.0
颜色假定在0.0 ... 1.0 范围内(例如对于OpenGL)。

C#

以下是用 C# 编写的相同函数:

private readonly Color mColor1 = Color.FromArgb(255, 0, 255, 0);
private readonly Color mColor2 = Color.FromArgb(255, 255, 255, 0);
private readonly Color mColor3 = Color.FromArgb(255, 255, 0, 0);

private Color GetInterpolatedColor(double interpolationFactor)
{
    double interpolationFactor1 = Math.Max(interpolationFactor - 0.5, 0.0);
    double interpolationFactor2 = 0.5 - Math.Abs(0.5 - interpolationFactor);
    double interpolationFactor3 = Math.Max(0.5 - interpolationFactor, 0.0);

    return (Color.FromArgb(255,
                (byte)((mColor1.R * interpolationFactor1 +
                        mColor2.R * interpolationFactor2 +
                        mColor3.R * interpolationFactor3) * 2.0),

                (byte)((mColor1.G * interpolationFactor1 +
                        mColor2.G * interpolationFactor2 +
                        mColor3.G * interpolationFactor3) * 2.0),

                (byte)((mColor1.B * interpolationFactor1 +
                        mColor2.B * interpolationFactor2 +
                        mColor3.B * interpolationFactor3) * 2.0)));
}

假定 interpolationFactor 的范围为 0.0 ... 1.0
颜色假定在 0 ... 255 范围内。

The accepted answer didn't even really answer the question...

C++

Here's a simple C++ code segment from my engine that linearly and efficiently interpolates between three arbitrary colors:

const MATH::FLOAT4 color1(0.0f, 1.0f, 0.0f, 1.0f);  // Green
const MATH::FLOAT4 color2(1.0f, 1.0f, 0.0f, 1.0f);  // Yellow
const MATH::FLOAT4 color3(1.0f, 0.0f, 0.0f, 1.0f);  // Red

MATH::FLOAT4 get_interpolated_color(float interpolation_factor)
{
    const float factor_color1 = std::max(interpolation_factor - 0.5f, 0.0f);
    const float factor_color2 = 0.5f - fabs(0.5f - interpolation_factor);
    const float factor_color3 = std::max(0.5f - interpolation_factor, 0.0f);

    MATH::FLOAT4 color;

    color.x = (color1.x * factor_color1 +
               color2.x * factor_color2 +
               color3.x * factor_color3) * 2.0f;

    color.y = (color1.y * factor_color1 +
               color2.y * factor_color2 +
               color3.y * factor_color3) * 2.0f;

    color.z = (color1.z * factor_color1 +
               color2.z * factor_color2 +
               color3.z * factor_color3) * 2.0f;

    color.w = 1.0f;

    return(color);
}

The interpolation_factor is assumed to be in the range of 0.0 ... 1.0.
The colors are assumed to be in the range of 0.0 ... 1.0 (e.g. for OpenGL).

C#

Here's the same function written in C#:

private readonly Color mColor1 = Color.FromArgb(255, 0, 255, 0);
private readonly Color mColor2 = Color.FromArgb(255, 255, 255, 0);
private readonly Color mColor3 = Color.FromArgb(255, 255, 0, 0);

private Color GetInterpolatedColor(double interpolationFactor)
{
    double interpolationFactor1 = Math.Max(interpolationFactor - 0.5, 0.0);
    double interpolationFactor2 = 0.5 - Math.Abs(0.5 - interpolationFactor);
    double interpolationFactor3 = Math.Max(0.5 - interpolationFactor, 0.0);

    return (Color.FromArgb(255,
                (byte)((mColor1.R * interpolationFactor1 +
                        mColor2.R * interpolationFactor2 +
                        mColor3.R * interpolationFactor3) * 2.0),

                (byte)((mColor1.G * interpolationFactor1 +
                        mColor2.G * interpolationFactor2 +
                        mColor3.G * interpolationFactor3) * 2.0),

                (byte)((mColor1.B * interpolationFactor1 +
                        mColor2.B * interpolationFactor2 +
                        mColor3.B * interpolationFactor3) * 2.0)));
}

The interpolationFactor is assumed to be in the range of 0.0 ... 1.0.
The colors are assumed to be in the range of 0 ... 255.

瑾夏年华 2024-07-16 22:52:33

您需要线性插值 (LERP) 颜色分量。 一般情况下是这样完成的,给定起始值 v0、结束值 v1 和所需的比率(0.0 到 1.0 之间的标准化浮点值) ):

v = v0 + ratio * (v1 - v0)

当比率为 0.0 时,给出 v0;当比率为 1.0 时,给出 v1;在其他情况下,给出介于两者之间的所有值。

您可以在 RGB 分量上执行此操作,也可以使用其他一些配色方案(例如 HSV 或 HLS)。 后两者在视觉上会更令人愉悦,因为它们处理的色调和亮度成分可以更好地映射我们的颜色感知。

You need to linearly interpolate (LERP) the color components. Here's how it's done in general, given a start value v0, an end value v1 and the required ratio (a normalized float between 0.0 and 1.0):

v = v0 + ratio * (v1 - v0)

This gives v0 when ratio is 0.0, v1 when ratio is 1.0, and everything between in the other cases.

You can do this either on the RGB components, or using some other color scheme, like HSV or HLS. The latter two will be more visually pleasing, since they work on hue and brightness compoments that map better to our color perception.

埋情葬爱 2024-07-16 22:52:33
import java.awt.Color;

public class ColorUtils {

    public static Color interpolate(Color start, Color end, float p) {
        float[] startHSB = Color.RGBtoHSB(start.getRed(), start.getGreen(), start.getBlue(), null);
        float[] endHSB = Color.RGBtoHSB(end.getRed(), end.getGreen(), end.getBlue(), null);

        float brightness = (startHSB[2] + endHSB[2]) / 2;
        float saturation = (startHSB[1] + endHSB[1]) / 2;

        float hueMax = 0;
        float hueMin = 0;
        if (startHSB[0] > endHSB[0]) {
            hueMax = startHSB[0];
            hueMin = endHSB[0];
        } else {
            hueMin = startHSB[0];
            hueMax = endHSB[0];
        }

        float hue = ((hueMax - hueMin) * p) + hueMin;

        return Color.getHSBColor(hue, saturation, brightness);
    }
}
import java.awt.Color;

public class ColorUtils {

    public static Color interpolate(Color start, Color end, float p) {
        float[] startHSB = Color.RGBtoHSB(start.getRed(), start.getGreen(), start.getBlue(), null);
        float[] endHSB = Color.RGBtoHSB(end.getRed(), end.getGreen(), end.getBlue(), null);

        float brightness = (startHSB[2] + endHSB[2]) / 2;
        float saturation = (startHSB[1] + endHSB[1]) / 2;

        float hueMax = 0;
        float hueMin = 0;
        if (startHSB[0] > endHSB[0]) {
            hueMax = startHSB[0];
            hueMin = endHSB[0];
        } else {
            hueMin = startHSB[0];
            hueMax = endHSB[0];
        }

        float hue = ((hueMax - hueMin) * p) + hueMin;

        return Color.getHSBColor(hue, saturation, brightness);
    }
}
百合的盛世恋 2024-07-16 22:52:33

以下是 Swift 和 HSV 比例的复制粘贴解决方案:

UIColor 初始值设定项接受 [0, 1] 中的色调、饱和度和亮度,因此对于来自 [0, 1] 的给定,我们有:

let hue:        CGFloat = value / 3
let saturation: CGFloat = 1 // Or choose any
let brightness: CGFloat = 1 // Or choose any
let alpha:      CGFloat = 1 // Or choose any

let color = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)

Here is copy-and-paste solution for Swift and HSV scale:

UIColor initializer accepts hue, saturation and brightness in [0, 1] so for given value from [0, 1] we have:

let hue:        CGFloat = value / 3
let saturation: CGFloat = 1 // Or choose any
let brightness: CGFloat = 1 // Or choose any
let alpha:      CGFloat = 1 // Or choose any

let color = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
机场等船 2024-07-16 22:52:33

如果您在 CSS(最低版本 2.1)中需要这种渐变(实际上是反向的),您也可以使用 HSL。

假设您在 AngularJs 模板中,值是从 0 到 1 的数字,并且您想要设置元素的样式(背景或文本颜色)...

hsl({{ value * 120}}, 50%, 35%)

第一个值:度数(0 红色,120 绿色)
第二个值:饱和度(50%为中性)
第三个值:亮度(50% 中性)

此处 一篇不错的

文章维基百科此处

If you need this kind of gradient (actually reversed) in CSS (min version 2.1) you can use HSL, too.

Supposing you are in an AngularJs template and value is a number from 0 to 1 and you want to style an element (background or text color)...

hsl({{ value * 120}}, 50%, 35%)

First value: degrees ( 0 red, 120 green)
Second value: saturation (50% is neutral)
Third value: lightness (50% neutral)

A nice article here

Theory on Wikipedia here

眼泪淡了忧伤 2024-07-16 22:52:33

以下是 Simucal 解决方案的 Objective-C 版本:

- (UIColor*) colorForCurrentLevel:(float)level
{
    double hue = level * 0.4; // Hue (note 0.4 = Green)
    double saturation = 0.9; // Saturation
    double brightness = 0.9; // Brightness

    return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1.0];
}

其中 level 是 0.01.0 之间的值。
希望这对某人有帮助!

Here is the Objective-C version of Simucal's solution:

- (UIColor*) colorForCurrentLevel:(float)level
{
    double hue = level * 0.4; // Hue (note 0.4 = Green)
    double saturation = 0.9; // Saturation
    double brightness = 0.9; // Brightness

    return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1.0];
}

Where level would be a value between 0.0 and 1.0.
Hope this helps someone!

爱格式化 2024-07-16 22:52:33

在 Python 2.7 中:

import colorsys

def get_rgb_from_hue_spectrum(percent, start_hue, end_hue):
    # spectrum is red (0.0), orange, yellow, green, blue, indigo, violet (0.9)
    hue = percent * (end_hue - start_hue) + start_hue
    lightness = 0.5
    saturation = 1
    r, g, b = colorsys.hls_to_rgb(hue, lightness, saturation)
    return r * 255, g * 255, b * 255

# from green to red:
get_rgb_from_hue_spectrum(percent, 0.3, 0.0)

# or red to green:
get_rgb_from_hue_spectrum(percent, 0.0, 0.3)

百分比当然是 value / max_value。 或者,如果您的比例不是从 0 开始,则(value - min_value) / (max_value - min_value)

In Python 2.7:

import colorsys

def get_rgb_from_hue_spectrum(percent, start_hue, end_hue):
    # spectrum is red (0.0), orange, yellow, green, blue, indigo, violet (0.9)
    hue = percent * (end_hue - start_hue) + start_hue
    lightness = 0.5
    saturation = 1
    r, g, b = colorsys.hls_to_rgb(hue, lightness, saturation)
    return r * 255, g * 255, b * 255

# from green to red:
get_rgb_from_hue_spectrum(percent, 0.3, 0.0)

# or red to green:
get_rgb_from_hue_spectrum(percent, 0.0, 0.3)

Percent is of course value / max_value. Or if your scale doesn't begin at 0 then (value - min_value) / (max_value - min_value).

沉默的熊 2024-07-16 22:52:33

JavaScript

我正在将 Google Visualization 与条形图结合使用,并希望条形根据百分比从绿色变为红色。 事实证明,这是我发现的最干净的解决方案并且工作完美。

function getGreenToRed(percent){
    r = percent<50 ? 255 : Math.floor(255-(percent*2-100)*255/100);
    g = percent>50 ? 255 : Math.floor((percent*2)*255/100);
    return 'rgb('+r+','+g+',0)';
}

只需确保您的百分比为 50 或 50%,而不是 0.50。

JavaScript

I am using Google Visualization with bar chart and wanted the bars to be green to red based on a percentage. This turned out to be the cleanest solution I found and works perfectly.

function getGreenToRed(percent){
    r = percent<50 ? 255 : Math.floor(255-(percent*2-100)*255/100);
    g = percent>50 ? 255 : Math.floor((percent*2)*255/100);
    return 'rgb('+r+','+g+',0)';
}

Just make sure your percentage is 50 for 50% and not 0.50.

葬シ愛 2024-07-16 22:52:33

我已经更新了接受的答案,将其分为 (0,100) 范围的前半部分和后半部分,并用最大级别替换 100,以便范围可以变得动态。 结果与 HSV 模型完全相同,但仍使用 RGB。 关键是中间的 (255,255,0) 代表黄色。 我已将这个想法结合在接受的答案和另一个 VBA 代码中,因此在 VBA 中实现它并在 Excel 中使用。 我希望该逻辑有所帮助并且可以在其他语言/应用程序中使用。

Sub UpdateConditionalFormatting(rng As Range)
    Dim cell As Range
    Dim max As Integer

    max = WorksheetFunction.max(rng)

    For Each cell In rng.Cells

    If cell.Value >= 0 And cell.Value < max / 2 Then
        cell.Interior.Color = RGB(255 * cell.Value / (max / 2), 255, 0)
    ElseIf cell.Value >= max / 2 And cell.Value <= max Then
        cell.Interior.Color = RGB(255, 255 * ((max) - cell.Value) / (max / 2), 0)
    End If

    Next cell
End Sub

干杯,
帕夫林

I have updated the accepted answer by spliting it into first and second half of the (0,100) range and substituting 100 by a max level, so that the range can become dynamic. The result is exactly as with the HSV model, but still using RGB. The key is to have the (255,255,0) in the middle to represent the yellow colour. I have combined this idea in the accepted answer and another VBA code, so achieve it in VBA and use in Excel. I hope the logic helps and can be used in other languages/ applications.

Sub UpdateConditionalFormatting(rng As Range)
    Dim cell As Range
    Dim max As Integer

    max = WorksheetFunction.max(rng)

    For Each cell In rng.Cells

    If cell.Value >= 0 And cell.Value < max / 2 Then
        cell.Interior.Color = RGB(255 * cell.Value / (max / 2), 255, 0)
    ElseIf cell.Value >= max / 2 And cell.Value <= max Then
        cell.Interior.Color = RGB(255, 255 * ((max) - cell.Value) / (max / 2), 0)
    End If

    Next cell
End Sub

Cheers,
Pavlin

北凤男飞 2024-07-16 22:52:33

VB

Public Function GetPercentageColor( _
  ByVal iPercent As Long, Optional _
  ByVal bOpposit As Boolean) As Long
' 0->100% - Green->Yellow->Red
' bOpposit - Red->Yellow->Green

If bOpposit Then iPercent = (100 - iPercent)

Select Case iPercent
Case Is < 1: GetPercentageColor = 65280 ' RGB(0, 255, 0)
Case Is > 99: GetPercentageColor = 255  ' RGB(255, 0, 0)
Case Is < 50: GetPercentageColor = RGB(255 * iPercent / 50, 255, 0)
Case Else: GetPercentageColor = RGB(255, (255 * (100 - iPercent)) / 50, 0)
End Select

End Function

VB

Public Function GetPercentageColor( _
  ByVal iPercent As Long, Optional _
  ByVal bOpposit As Boolean) As Long
' 0->100% - Green->Yellow->Red
' bOpposit - Red->Yellow->Green

If bOpposit Then iPercent = (100 - iPercent)

Select Case iPercent
Case Is < 1: GetPercentageColor = 65280 ' RGB(0, 255, 0)
Case Is > 99: GetPercentageColor = 255  ' RGB(255, 0, 0)
Case Is < 50: GetPercentageColor = RGB(255 * iPercent / 50, 255, 0)
Case Else: GetPercentageColor = RGB(255, (255 * (100 - iPercent)) / 50, 0)
End Select

End Function
情释 2024-07-16 22:52:33

自包含示例

<html>
<head>
<script>
//--------------------------------------------------------------------------
function gradient(left, mid, right)
{
    var obj = {}

    var lt50 = {"r":(mid.r-left.r)/50.0,
                "g":(mid.g-left.g)/50.0,
                "b":(mid.b-left.b)/50.0}
    var gt50 = {"r":(right.r-mid.r)/50.0,
                "g":(right.g-mid.g)/50.0,
                "b":(right.b-mid.b)/50.0}

    obj.getColor = function(percent) {
        if (percent == 50.0) {
            return mid;
        }
        if (percent < 50.0) {
            return "rgb("+Math.floor(left.r+lt50.r*percent+0.5)+","+
                          Math.floor(left.g+lt50.g*percent+0.5)+","+
                          Math.floor(left.b+lt50.b*percent+0.5)+")";
        }
        var p2 = percent-50.0;
        return "rgb("+Math.floor(mid.r+gt50.r*p2+0.5)+","+
                      Math.floor(mid.g+gt50.g*p2+0.5)+","+
                      Math.floor(mid.b+gt50.b*p2+0.5)+")";
    }

    return obj;
}

//--------------------------------------------------------------------------
var g_gradient = gradient( {"r":255, "g":20, "b":20},  // Left is red
                           {"r":255, "g":255, "b":20}, // Middle is yellow
                           {"r":20, "g":255, "b":20} ); // right is green

//--------------------------------------------------------------------------
function updateColor()
{
    var percent = document.getElementById('idtext').value.length;
    var oscore = document.getElementById('idscore');

    if (percent > 100.0) {
        percent = 100.0;
    }
    if (percent < 0.0) {
        percent = 0.0;
    }
    var col = g_gradient.getColor(percent)
    oscore.style['background-color'] = col;
    oscore.innerHTML = percent + '%';
}

</script>
</head>
<body onLoad="updateColor()">
<input size='100' placeholder='type text here' id='idtext' type="text" oninput="updateColor()" />
<br />
<br />
<div id='idscore' style='text-align:center; width:200px; border-style:solid;
     border-color:black; border-width:1px; height:20px;'> </div>
</body>
</html>

Self contained example

<html>
<head>
<script>
//--------------------------------------------------------------------------
function gradient(left, mid, right)
{
    var obj = {}

    var lt50 = {"r":(mid.r-left.r)/50.0,
                "g":(mid.g-left.g)/50.0,
                "b":(mid.b-left.b)/50.0}
    var gt50 = {"r":(right.r-mid.r)/50.0,
                "g":(right.g-mid.g)/50.0,
                "b":(right.b-mid.b)/50.0}

    obj.getColor = function(percent) {
        if (percent == 50.0) {
            return mid;
        }
        if (percent < 50.0) {
            return "rgb("+Math.floor(left.r+lt50.r*percent+0.5)+","+
                          Math.floor(left.g+lt50.g*percent+0.5)+","+
                          Math.floor(left.b+lt50.b*percent+0.5)+")";
        }
        var p2 = percent-50.0;
        return "rgb("+Math.floor(mid.r+gt50.r*p2+0.5)+","+
                      Math.floor(mid.g+gt50.g*p2+0.5)+","+
                      Math.floor(mid.b+gt50.b*p2+0.5)+")";
    }

    return obj;
}

//--------------------------------------------------------------------------
var g_gradient = gradient( {"r":255, "g":20, "b":20},  // Left is red
                           {"r":255, "g":255, "b":20}, // Middle is yellow
                           {"r":20, "g":255, "b":20} ); // right is green

//--------------------------------------------------------------------------
function updateColor()
{
    var percent = document.getElementById('idtext').value.length;
    var oscore = document.getElementById('idscore');

    if (percent > 100.0) {
        percent = 100.0;
    }
    if (percent < 0.0) {
        percent = 0.0;
    }
    var col = g_gradient.getColor(percent)
    oscore.style['background-color'] = col;
    oscore.innerHTML = percent + '%';
}

</script>
</head>
<body onLoad="updateColor()">
<input size='100' placeholder='type text here' id='idtext' type="text" oninput="updateColor()" />
<br />
<br />
<div id='idscore' style='text-align:center; width:200px; border-style:solid;
     border-color:black; border-width:1px; height:20px;'> </div>
</body>
</html>
幸福丶如此 2024-07-16 22:52:33

颜色会从红色变为黄色,然后变为绿色
值范围为 0 - 100

-(UIColor*) redToGreenColorWithPosition:(int) value {

    double R, G;
    if (value > 50) {
        R = (255 * (100 - value)/ 50) ;
        G = 255;
    }else {
        R = 255;
        G = (255 * (value*2)) / 100;
    }

    return [UIColor colorWithRed:R/255.0f green:G/255.0f blue:0.0f alpha:1.0f];
}

This will vary from Red to Yellow and then to Green
value varies from 0 - 100

-(UIColor*) redToGreenColorWithPosition:(int) value {

    double R, G;
    if (value > 50) {
        R = (255 * (100 - value)/ 50) ;
        G = 255;
    }else {
        R = 255;
        G = (255 * (value*2)) / 100;
    }

    return [UIColor colorWithRed:R/255.0f green:G/255.0f blue:0.0f alpha:1.0f];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文