2012-01-02 27 views
2

現在、私はC#のマンデルブロフラクタルジェネレータプログラムに取り組んでいます。私は色分けのために、線形補間とルックアップテーブルとしての配列を使用しています。双線形補間カラースキーム

直線補間の問題は、2色しか使用できないことです。

少なくとも3色を使用したいと思いますが、私は双線形補間プログラミングアルゴリズムを探していましたが、良いものは見つかりませんでした。

あなたの誰かがこれに対する解決策を持っているのだろうかと思いました。

は、ここに私の線形補間コードです:

private void InitColors() 
{ 
    int range = 255; 
    lookup = new Color[range]; 
    Color from = Color.White; 
    Color to = Color.Blue; 
    int red; 
    int green; 
    int blue; 

    for (int i = 0; i < range; i++) 
    { 
     red = ((from.R * (range - i)) + (to.R * i))/range; 
     green = ((from.G * (range - i)) + (to.G * i))/range; 
     blue = ((from.B * (range - i)) + (to.B * i))/range; 
     lookup[i] = Color.FromArgb(red, green, blue); 
    } 
} 

EDIT:おそらく以上の2つの色の間の勾配を得るためにバイリニアよりも簡単な補間があります。

+2

線形補間は、2つの色の間に勾配を与えます。しかし、3つの色を補間したい場合は、少なくとも2つの自由度が必要です。色選択を駆動するために使用したい(2つ以上の)変数は正確には何ですか?再帰の深さ? X座標?平面内の任意の点からの距離? – Peter

+0

2色以上の勾配の結果が得られる限り、どのような方法を使用するかは本当に気にしません。しかし、もし存在すれば、私は非常に単純なものを望んでいます:-P –

答えて

2

あなたがしていることは、実際には双線形補間とは呼ばれません。バイリニアは0-1の範囲内の2つの引数iおよびjを使用して、2Dカラーマップを意味し、使用して4色のブレンド、それら2つのI、J値 - すなわちC_ijコーナー色である

C = C_00 (1-i) (1-j) + C_10 * i * (1-j) + C_01 * (1-i) * j + C_11 * i * j 

あなたが本当に望むのは、複数の色を含むグラデーションを作成することですが、1つのパラメータを使用して1次元であることがわかります。これを行うにはさまざまな方法があります。これらの中で最も簡単なものは、0〜0.5の範囲にわたって色Aから色Bに、0.5〜1.0の範囲にわたってBからCに混合することである。

もちろん、3色以上の色に分割することもできます。

コードがこのようなものになります行うには:

private void InitColors(Color * colors, int n_colors) 
{ 
    int range = 255; 
    lookup = new Color[range]; 
    int red; 
    int green; 
    int blue; 

    for (int i = 0; i < range; i++) 
    { 
     float f = float(i)/float(range); 
     //Work out which interval we're in 
     int interval = f*(n_colors); 

     //Special case for the end point to prevent out-of-bounds access. 
     if(f>=1.0) { interval = n_colors-1; } 

     //Work out how far into that interval we are 
     float ff = f * (n_colors-1) - interval; 

     int R = (colors[interval].R * (1-f) + colors[interval+1].R*f; 
     int G = (colors[interval].G * (1-f) + colors[interval+1].G*f; 
     int B = (colors[interval].B * (1-f) + colors[interval+1].B*f; 

     lookup[i] = Color.FromArgb(R, G, B); 
    } 
} 

今、あなたはおそらく気にしないだろうこれで問題のカップルがありますが、私は念のために言及します:

  • これは非常に滑らかな色の遷移ではありません。スムーズな振る舞いが必要な場合は、スプラインベースのアプローチを使用する必要があります(これは技術的には最も単純なバージョンです)。私はCattmul-Romスプラインを調べることをお勧めします。

  • 色の変化は、あまり均一ではありません。私は、RGB以外の空間で計算を行い、最後にRGBに変換することを検討したいと思います。このために私はLabスペース(HSVは別のオプションですが、その後、あなたはH方向にラップを心配する必要があります。)

・ホープこのことができますを検討したいです。

+0

"双線形は2つの引数iとjを意味します"これらの引数は何を意味しますか? – shim

+0

その例を明確にしました(うまくいけば)。 –

+0

だから彼らは任意の係数ですか? – shim

1

あなたのコードで示唆されているように、すべての色はユークリッド3空間のベクトルとして表されるかもしれません。

3つの任意の色C1、C2、C3が与えられたら、まず、関連するRGBベクトルv1、v2、v3を見つけ、すべての「凸の組み合わせ」を取って各ベクトルの先端に頂点を持つ三角形領域を構築するこれら3つのベクトルの:C1、C2、及びC3はスカラー0と1の間の値、およびC1 + C2 + C3 = 1、およびベクトル加算(及びスカラー乗算)の通常のユークリッド規則である

c1 * v1 + c2 * v2 + c3 * v3 

適用。

注:これは、任意の数の色に対しても機能します。 N個の色についてはN個の関連ベクトルがあり、これらのベクトルの「凸組合せ」はN-1次元の「シンプレックス」です。すべて線形で、計算が非常に簡単です。しかし、この方法で生成された色の勾配は、審美的には最適ではないかもしれません。非線形の方法では、より美しい結果が得られるかもしれません。

EDIT:N> 3ならば、あなたの「ベクター」はすべて3次元であるRGB空間に住んでいる、とそうすべてのことができないため幾何学的には、N個の頂点を持つあなたの「シンプレックス」を話すことは、実際に、次元N-1ではありません線形独立。これは一般的に(N> 3の場合)座標が異なるが、見かけの "色"が同じである "シンプレックス"内に多くの点が存在することを意味します。

+0

三角地域ではどうしますか? – shim

関連する問題