パワーメーターの赤と緑の間の色を生成しますか?


137

私はJavaゲームを書いていて、あなたが何かを撮影するのがどれだけ難しいかについてパワーメーターを実装したいと思います。

0〜100のintをとる関数を作成する必要があります。その数値の高さに基づいて、緑(パワースケールで0)と赤(パワースケールで100)の間の色を返します。

音量調節のしくみに似ています:
音量調節

緑と赤の間で色を生成するために、色の赤、緑、青のコンポーネントに対してどのような操作を行う必要がありますか?

だから、私は言うことができる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);
}

「パワー」は0.0〜1.0の数値です。0.0は明るい赤を返し、1.0は明るい緑を返します。

Java Hueチャート:
Java Hueチャート


私は以前にここで同じ(非常に類似した)質問をしました:http
//stackoverflow.com/questions/168838/color-scaling-function

2
あなたは力を逆にしてはいけませんか?赤が最高のヒットであり、0.1と0.4の間で作業している場合、パワーが高いほどHは低くなります
Adriaan Davel

OpenGLを使用していますか?三角形のポイントを異なる色に設定し、それらの間でブレンド/グラデーションを行う方法があるためです。おそらく、グラフィックカードに作業を依頼することで、パフォーマンスが向上します。また、コードはよりシンプル/より適応可能になる可能性があります(たとえば、エイリアンパワーメーターを緑から青にしたい場合)
DarcyThomas

回答:


203

これはうまくいくはずです-赤と緑の値を線形にスケーリングするだけです。赤、緑255、青の最大値がでありn、範囲内であると仮定します0 .. 100

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

(整数演算用に修正、フェルッチオへの帽子の先端)

別の方法としては、HSVカラーモデルを使用し、色相を0 degrees(赤)から120 degrees(緑)に、彩度と値が適切なもので循環させます。これにより、より楽しいグラデーションが得られます。

以下は各手法のデモンストレーションです-上のグラデーションはRGBを使用し、下のグラデーションはHSVを使用します:

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


20
HSV空間でこれを行う方がはるかに優れています。
DJクレイワース2008

@DJClayworth、そう、HSVと一緒に行きました。
mmcdole 2009年

+1; HTML / PHPで棒グラフを色付けするための色アルゴリズムを改善する方法について新しい質問をするつもりでした... SOもこの質問を同様に提案し、あなたの答えが質問することなく問題を修正するのに役立ちました!ありがとう!
2009

どのようなカラー値でも機能する関数をどのように記述しますか?たとえば、RGB 20,30,190とRBG 69,190,10の間の色を計算しますか?
Kokodoko 2014

1
同じ手法-値Xから値YにNステップで移動するには、各ステップでXを(YX)/ Nずつインクリメントします-RGBではなくHSV空間で移動する方が見栄えがよくなります
Paul Dixon

32

私の頭の上で、これはRGBに変換されたHSV空間の緑と赤の色相遷移です:

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で乗算する必要があります。


12

短いコピーと貼り付けの回答...

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までの数値で、赤から緑の状態を示します。


16進数のカラーコードに直接変換するには、活用したい場合がありますString.format("#%06X", 0xFFFFFF & getTrafficlightColor(value));
ngeek

10

受け入れられた回答が示唆するような緑黄赤の表現が必要な場合は、これを見てください。

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 1,255,0を返します:0.277、0.222、0.111 ...高い値(たとえば1.0)は明るい緑の正しいRGBを返しますが、しきい値の後でトレイリングが停止し、私のスケールの緑の色合い。
Patrick

8

緑と赤の間の線形補間は、真ん中に濁った茶色があることを除いて、ほとんど機能するはずです。

最も柔軟で最も見栄えの良いソリューションは、希望する正確なカラーランプを持つ画像ファイルをどこかに配置することです。そして、そこでピクセル値を検索します。これには、グラデーションを微調整して適切に調整できるという柔軟性があります。

それでもコードから実行する場合は、左側の緑と黄色の間、および右側の黄色と赤の間を補間するのがおそらく最善です。RGB空間では、緑は(R = 0、G = 255、B = 0)、黄色は(R = 255、G = 255、B = 0)、赤は(R = 255、G = 0、B = 0)です。 )-これは、各カラーコンポーネントが0〜255になることを前提としています。


1
ここでスペクトルを赤/黄と黄/緑に分割するという提案は、最も心地よい黄色の結果をもたらします。
イチジク

4

パーセンテージ値の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の場合、この関数は必要な色を返すため、この関数をパーセント値でループすると、色の値は緑から赤に変わります。悪い説明でごめんなさい


3

受け入れられた答えは本当に質問に答えさえしませんでした...

C ++

これは、3つの任意の色の間を線形かつ効率的に補間する、私のエンジンからの単純な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


1
C#のコードは私のために働いた華麗な(追加をupvote)それinterpolationFactorColor2でスペルミスがinterpolationFactor2する必要がありますあり
DJIDave

また、完全を期すために、関数を使用してRGBをMVC razrビューに返す方法を示しますdouble n = actualValue / maxValue; //これにより、比率が0-1になります。return string.Concat( "#"、colour.R.ToString( "X")、colour.G.ToString( "X")、colour.B.ToString( "X"));
DJIDave

@DJIDave:うわー、なんて明白で愚かな間違いでしょう。私はそれを修正しました。ありがとう!
Tara

2

色成分を線形補間(LERP)する必要があります。開始値v0、終了値v1、および必要な比率(0.0と1.0の間の正規化された浮動小数点数)が与えられた場合の一般的な方法は次のとおりです。

v = v0 + ratio * (v1 - v0)

これにより、ratioが0.0の場合はv0、ratioが1.0の場合はv1、その他の場合はその間のすべてが得られます。

これは、RGBコンポーネントで行うか、HSVやHLSなどの他のカラースキームを使用して行うことができます。後者の2つは、色の知覚によりよく対応する色相と明るさの成分に作用するため、視覚的にはより楽しいものになります。


2

HSVスペースのラインセグメント(中央がやや明るすぎる黄色)とRGBスペースのラインセグメント(中央が醜い茶色)の間に何かを配置するとします。私はこれを使用します。ここでpower = 0は、緑power = 50を与え、わずかにくすんだ黄色power = 100を与え、赤を与えます。

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

2

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)

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

1

CSS(最小バージョン2.1)でこの種のグラデーション(実際には反転)が必要な場合は、HSLも使用できます。

AngularJsテンプレートを使用していて、値が0〜1の数値であり、要素(背景またはテキストの色)のスタイルを設定するとします。

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

最初の値:度(赤0、緑120)2番目の値:彩度(50%はニュートラル)3番目の値:明度(50%ニュートラル)

ここに素敵な記事

ウィキペディアの理論はこちら


1

ここでObjective-CSimucalのソリューションのバージョンは:

- (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.0なり1.0ます。
これが誰かを助けることを願っています!


1

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)


1

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

割合が0.50 ではなく 50%の50であることを確認してください。


1

受け入れられた回答を(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

乾杯、パブリン


1

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

これはうまくいくかもしれませんが、説明を提供してくれると助かります
David Glickman

0

自己完結型の例

<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>

0

これは、赤から黄色、次に緑の
値が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];
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.