私はJavaゲームを書いているので、あなたが何かを撃つのがどれだけ難しいかについてパワーメーターを実装したいと思います。
0〜100の整数を取る関数を作成する必要があり、その数値の大きさに基づいて、緑(パワースケールで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);
}
ここで、「power」は0.0〜1.0の数値です。 0.0は明るい赤を返し、1.0は明るい緑を返します。
Java Hue Chart:
これは機能するはずです-赤と緑の値を線形にスケーリングするだけです。赤/緑/青の最大値が255
、およびn
の範囲は0 .. 100
R = (255 * n) / 100
G = (255 * (100 - n)) / 100
B = 0
(整数計算用に修正、Ferlucioの帽子の先端)
別の方法として、 HSVカラーモデル を使用し、0 degrees
(赤)から120 degrees
(緑)どんな彩度と値でもあなたに合ったもの。これにより、より心地よいグラデーションが得られます。
各手法のデモを次に示します-上部のグラデーションはRGBを使用し、下部のグラデーションはHSVを使用します。
私の頭の上の、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を乗算する必要があります。
短いコピーと貼り付けの答え...
On 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の数値です。
緑と赤の間の線形補間almostは機能しますが、真ん中には濁った茶色があります。
最も柔軟で見栄えの良いソリューションは、希望する正確なカラーランプを持つイメージファイルをどこかに置くことです。そして、そこでピクセル値を検索します。これには、グラデーションをjust rightに微調整できる柔軟性があります。
それでもコードから実行したい場合は、左側の緑と黄色の間、右側の黄色と赤の間を補間するのがおそらく最善です。 RGB空間では、緑は(R = 0、G = 255、B = 0)、黄色は(R = 255、G = 255、B = 0)、赤は(R = 255、G = 0、B = 0) )-これは、各色成分が0から255になることを前提としています。
受け入れられた答えが示唆するような緑黄赤の表現が必要な場合は、これを見てください。
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整数値を提供する小さな関数を作成しました。
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++コードセグメントです。
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
の範囲にあると想定されます。
色成分を 線形補間 (LERP)する必要があります。一般的な方法は、開始値v0、終了値v1および必要なratio(0.0から1.0の間の正規化されたフロート):
v = v0 + ratio * (v1 - v0)
これにより、比率が0.0の場合はv0、比率が1.0の場合はv1、その他の場合はその間のすべてが得られます。
これは、RGBコンポーネントで実行するか、HSVやHLSなどの他のカラースキームを使用して実行できます。後者の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 ));
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)
パーセントはもちろんvalue / max_value
。または、スケールが0で始まらない場合は、(value - min_value) / (max_value - min_value)
。
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);
}
}
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.0
と1.0
の間の値です。
これが誰かの助けになることを願っています!
SwiftおよびHSVスケールのコピーアンドペーストソリューションは次のとおりです。
UIColor初期化子は、[0、1]の色相、彩度、明度を受け入れるので、与えられたvalue [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)
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であり、not0.50であることを確認してください。
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
受け入れられた回答を(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
乾杯、パブリン
これは赤から黄色、そして緑に変わります
値の範囲は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];
}
自己完結型の例
<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>