2009-03-20 9 views
5

時間をかけて(240時間)色を明るい緑から暗い赤に変更したいと思います。私が見ることができる最善の方法は、00FF00からFF0000への16進数のコンボを変更することです。アルゴリズム質問:TIME、C#/ Javaで00FF00からFF0000まで動的にインクリメントする必要があります。

私はFF0000から00FF00まで動的にカウントする方法がわかりません。私は10日以上の期間を見ているので、240時間以上かかる可能性が最も高いです。

誰でもお手伝いできますか?

私は決してアルゴリズムクラスを取ったことがないので、この問題と関係があると思います。

これを行うより良い方法があれば、教えてください。

私はここで何らかのコードを探しています。みんなありがとう。どの言語でも構いませんが、必然的にC#に変換されます。

答えて

8

コンポーネントについて考えてみましょう。 1つの大きな16進数のように見えますが、実際には3つ並んでいます。赤色開始時

は、緑色、0である青色、255(FF)である最後に0
で、赤、緑、255で青、0になるように0

である、すべての(量あなたは/ 255を持っている時間)を、1

+0

どちらも正しいです。両方の人に答えを与えたいと思います。 –

+0

チャット・バーチはピート・カークハムの答えよりもはるかに簡単なので、スコットは良い選択をしました。 –

3

TIME_REMAINING(値は0から239まで変化する)

緑= 255 *(TIME_REMAINING/239)
=赤255で1とデクリメント緑に赤インクリメント - 緑色
青色= 0

色=(赤、緑、青)

+0

どちらも正しいです。両方の人に答えを与えたいと思います。 –

29

進値が示唆するようあなたは明るい色に明るい色から予定している場合、あなたはむしろ、RGB空間よりも、HSV spaceで補間することを望むかもしれません。 HSV空間は、色相、彩度および価値についてどのように考えているかを概算します。 RGB空間は、我々の目の光感受性細胞がどのように働くかを近似する。

上側勾配は、FF0000から00FF00までの線形RGB補間です。その真ん中の値は7f7f00で、泥だらけの茶色です。

中間勾配は、HSV空間の線形補間です。 FF0000と00FF00の両方が完全に飽和し、同じ値(明るさ)を持つので、補間は同じ輝度と彩度を維持しますので、中央値は明るい黄色ffff00です。

第3の代替案は、中間値がB4B400(B4hex = 180 dec = 255/sqrt(2))であることを意味する、RGB空間におけるベクトル回転であり、これは2つの効果の間にある。これは、各端点の大きさを計算し、RGB線形補間の結果を同じ大きさになるようにスケーリングして、2つの色の平面と原点の円弧内のベクトルを効果的にスイープします。実際に明るさのために異なる色を均等に重み付けしたり、直線的に見ることはしませんが、それは正確ではありませんが、HSVは中央で少し明るいのに対し、スイープではかなり均一な強度を持っています。 100%である。あなたはHSBのアルゴリズムをサポートしていたJavaでは、

削除死んImageShackのリンク


簡単です - 終了値のHSB、線形を変換し、その後、他のRGBの答えのようにそれらを補間ますV値、sは、時間とともに色を作成します。

static Color hsvInterpolate (float mix, Color c0, Color c1) { 
    float[] hsv0 = new float[3]; 
    float[] hsv1 = new float[3]; 

    float alt = 1.0f - mix; 

    Color.RGBtoHSB(c0.getRed(), c0.getGreen(), c0.getBlue(), hsv0); 
    Color.RGBtoHSB(c1.getRed(), c1.getGreen(), c1.getBlue(), hsv1); 

    float h = mix * hsv0 [ 0 ] + alt * hsv1 [ 0 ]; 
    float s = mix * hsv0 [ 1 ] + alt * hsv1 [ 1 ]; 
    float v = mix * hsv0 [ 2 ] + alt * hsv1 [ 2 ]; 

    return Color.getHSBColor (h, s, v); 
} 

私はC#は内蔵の変換を持っていると信じていないので、コードは実際に多くの使用ではありません。

static Color vectorInterpolate (float mix, Color c0, Color c1) { 
    float alt = 1.0f - mix; 

    double x0 = c0.getRed(); 
    double y0 = c0.getGreen(); 
    double z0 = c0.getBlue(); 

    double x1 = c1.getRed(); 
    double y1 = c1.getGreen(); 
    double z1 = c1.getBlue(); 

    double mag0 = sqrt(x0*x0 + y0*y0 + z0*z0); 
    double mag1 = sqrt(x1*x1 + y1*y1 + z1*z1); 

    double x = mix * x0 + alt * x1; 
    double y = mix * y0 + alt * y1; 
    double z = mix * z0 + alt * z1; 

    double mag = mix * mag0 + alt * mag1; 
    double scale = mag/sqrt(x*x + y*y + z*z); 

    return new Color ( 
     clamp (x * scale), 
     clamp (y * scale), 
     clamp (z * scale)); 
} 

static int clamp (double value) { 
    int x = (int) round (value); 

    if (x > 255) return 255; 
    if (x < 0) return 0; 
    return x; 
} 

おそらくRGB立方体の辺のベクトルの交点ではなく、単にそれをクランプを見つけたいが、この場合には、それはどちらの方法でもかまいません。添加物として


Dave Green's cube helix

色補間によって示されるように、それは、また、知覚される明るさに近いHSY空間を検討する価値があります。

+0

これを行う方法の例はいいですね=) – Svish

+0

クールな答え! wikipediaの記事でもrgbとhsvの間の変換演算があるので、C#での実装が可能でなければなりません。つまり、HSVで表現される色の直接サポートはないと思います... – flq

+0

+1私に何か新しいことを教えるため – Nifle

0

ここに(あなたがそれを変更することができOFC)が赤から緑への迅速なJavaの答えの値が時間内の現在のvalueあるとallは時間の合計です...

public static String progressiveColor(int value, int all){ 

    int red = 255 - (int)((float)(value*255)/(float)all); 
    int green = (int)((float)(value*255)/(float)all); 
    return String.format("#%06X", (0xFFFFFF & Color.argb(255, red, green, 0))); 

} 
0

ここピートのJavaコードがあります誰かがそれを探していた場合に備えてC#に翻訳されています。私の目的(黒から暗赤、背中)は素晴らしい作品です。

static Color VectorInterpolate(float mix, Color c0, Color c1) 
    { 
     float alt = 1.0f - mix; 

     double x0 = c0.R; 
     double y0 = c0.G; 
     double z0 = c0.B; 

     double x1 = c1.R; 
     double y1 = c1.G; 
     double z1 = c1.B; 

     double mag0 = Math.Sqrt(x0 * x0 + y0 * y0 + z0 * z0); 
     double mag1 = Math.Sqrt(x1 * x1 + y1 * y1 + z1 * z1); 

     double x = mix * x0 + alt * x1; 
     double y = mix * y0 + alt * y1; 
     double z = mix * z0 + alt * z1; 

     double mag = mix * mag0 + alt * mag1; 
     double scale = mag/Math.Sqrt(x * x + y * y + z * z); 

     return Color.FromRgb(Clamp(x * scale), Clamp(y * scale), Clamp(z * scale)); 
    } 

    static byte Clamp(double value) 
    { 
     var x = (int)Math.Round(value); 

     if (x > 255) return 255; 
     if (x < 0) return 0; 
     return (byte) x; 
    } 
関連する問題