5

ユーザーが選択した 2 つの色の間の虹色のグラデーションを表示するグラデーション ビットマップを生成する必要があります。虹を生成するのは簡単です。以下のコードはWikiから取得し、わずかに変更したものです。高速でシンプルであるという利点があります。

 function TColor_Dialog.GiveRainbowColor (fraction: double): TAlphaColor;
  var
    m: Double;
    r, g, b, mt: Byte;
  begin
    if fraction <= 0 then m := 0 else
    if fraction >= 1 then m := 6
                     else m := fraction * 6;
    mt := (round (frac (m) * $FF));
    case Trunc (m) of
    0: begin
        R := $FF;
        G := mt;
        B := 0;
      end;
    1: begin
        R := $FF - mt;
        G := $FF;
        B := 0;
      end;
    2: begin
        R := 0;
        G := $FF;
        B := mt;
      end;
    3: begin
        R := 0;
        G := $FF - mt;
        B := $FF;
      end;
    4: begin
        R := mt;
        G := 0;
        B := $FF;
      end;
    5: begin
        R := $FF;
        G := 0;
        B := $FF - mt;
      end;
    end; // case

    Result := ColorToQuad (r, g, b);
  end; // GiveRainbowColor //

このアルゴリズムの問​​題点は、2 つの色の間の部分的な虹を表示できないことです。もちろん、それは可能ですが、各色の割合に近づく必要があり、私はその解決策が好きではありません. 色を r、g、b チャンネルに分解しようとしましたが、うまくいきませんでした。その理由は後から考えれば明らかです。FF0000 と 0000FF の間のグラデーションが必要だとします。FF->00 から赤色に変換し、00->FF から青色に変換します。ただし、虹のグラデーションにはっきりと存在する緑 (00FF00) はありません。

私が必要としているのは、2 つの色と分数を与えることができ、色を生成するグラデーション関数です。誰か記事、アルゴリズム、さらにはコードを教えてもらえますか?

アップデート

NGLN の回答は、この質問に対する正解です。彼とウォーレンはどちらも、色が明るい色 (0、$FF、および値を含む色)ではない場合にどうすればよいか疑問に思いました。アップ/ダウンスケーリングとHSL補間など、いくつかの角度を試しました。私は最終的に、最も単純なものとして最後のものに落ち着きました。

基本的に、 と の 2 つの色がfromありtoます。RGBtoHSL を使用して、各色から HSL パラメーターを抽出しますRGBtoHSL (col_from, hf, sf, lf)。次に、両方の色の色相、彩度、および輝度を計算し、新しい色を再構築します。これは、NGLN が色相に関する最新情報で述べていることですが、この原則を一般化すると、任意の色の間に虹があります。

function TColor_Dialog.interpolate_hsl (col_from, col_to: TAlphaColor; fraction: double): TAlphaColor;
  var af, at, ad: uInt8;
      hf, ht, hd: single;
      sf, st, sd: single;
      lf, lt, ld: single;
  begin
  // Get each rgb color channel
     af := GetAValue (col_from);
     at := GetAValue (col_to);
     RGBtoHSL (col_from, hf, sf, lf);
     RGBtoHSL (col_to,   ht, st, lt);

  // Compute differences
     ad := af + Round (fraction * (at - af));
     hd := hf + fraction * (ht - hf);
     sd := sf + fraction * (st - sf);
     ld := lf + fraction * (lt - lf);

     Result := MakeColor (HSLtoRGB (hd, sd, ld), ad);
  end; // interpolate_hsl //

これにより、可能なすべての色の虹が得られます。不透明度にも同じ補間を適用するため、 を使用しMakeColorて、補間されたアルファ チャネルを色に「いじる」ことができます。

ここに画像の説明を入力

4

1 に答える 1