[language-agnostic] 파워 미터에 빨간색과 녹색 사이의 색상을 생성 하시겠습니까?

Java 게임을 작성 중이며 무언가를 얼마나 열심히 쏠 지에 대한 파워 미터를 구현하고 싶습니다.

0에서 100 사이의 정수를 취하는 함수를 작성해야하며 그 숫자의 높이에 따라 녹색 (파워 스케일에서 0)과 빨간색 (파워 스케일에서 100) 사이의 색상을 반환합니다.

볼륨 컨트롤의 작동 방식과 유사합니다 :
볼륨 조절

녹색과 빨간색 사이의 색상을 생성하려면 색상의 빨강, 녹색 및 파랑 구성 요소에서 어떤 작업을 수행해야합니까?

그래서 나는 말할 수 있고 getColor(80), 그것은 오랑 지 색상 (R, G, B의 값) getColor(10)을 반환하거나 더 녹색 / 노란색 RGB 값을 반환합니다.

새 색상에 대해 R, G, B 값의 구성 요소를 늘려야한다는 것을 알고 있지만 녹색-빨간색에서 색상이 이동함에 따라 무엇이 올라가거나 내려가는 지 구체적으로 알 수 없습니다.


진행:

나는 gradiant를 더 좋아했기 때문에 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은 밝은 녹색을 반환합니다.

자바 색조 차트 :
자바 색조 차트



답변

이것은 작동해야합니다-빨강 및 녹색 값을 선형으로 조정하십시오. 최대 빨강 / 녹색 / 파랑 값이 255이고 n범위 내에 있다고 가정0 .. 100

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

(정수 수학, Ferrucio의 모자 팁 수정)

또 다른 방법은 HSV 색상 모델 을 사용하고 채도 및 값에 따라 색조를 0 degrees(적색)에서 120 degrees(녹색)으로 순환시키는 것입니다. 이것은 더 즐거운 그라디언트를 제공해야합니다.

다음은 각 기법의 데모입니다. 상단 그라디언트는 RGB를 사용하고 하단은 HSV를 사용합니다.

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


답변

내 머리 꼭대기에서 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)

위의 예에서 빨강, 녹색, 파랑 값은 백분율이므로 가장 많이 사용되는 0-255 범위를 얻기 위해 255를 곱하는 것이 좋습니다.


답변

Short Copy’n’Paste 답변 …

Java Std에서 :

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

안드로이드 :

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

참고 : 값은 빨강-녹색 조건을 나타내는 0과 1 사이의 숫자입니다.


답변

허용 된 답변과 같은 녹색-노랑-빨강 표현을 원한다면 이것을보십시오.

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>


답변

녹색과 빨간색 사이의 선형 보간은 거의 작동해야합니다. 단, 중간에는 진흙 갈색이 있습니다.

가장 유연하고 가장보기 좋은 솔루션은 원하는 정확한 색상 램프가있는 이미지 파일을 어딘가에 배치하는 것입니다. 그런 다음 픽셀 값을 찾아보십시오. 그래디언트를 올바르게 조정할 수있는 유연성이 있습니다 .

여전히 코드에서 코드를 작성하려면 왼쪽의 녹색과 노란색 사이, 오른쪽의 노란색과 빨간색 사이를 보간하는 것이 가장 좋습니다. RGB 공간에서 녹색은 (R = 0, G = 255, B = 0), 노랑은 (R = 255, G = 255, B = 0), 빨강은 (R = 255, G = 0, B = 0) )-각 색상 구성 요소가 0에서 255로 가정합니다.


답변

작은 함수로 백분율 값에 대한 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 인 경우이 함수는 필요한 색상을 반환하므로이 함수를 백분율 값으로 반복하면 색상 값이 녹색에서 빨간색으로 바뀝니다. 나쁜 설명으로 죄송합니다


답변

수락 된 답변은 실제로 질문에 대답하지 못했습니다 …

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 #으로 작성된 동일한 기능은 다음과 같습니다.

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.