http://www.fourmilab.ch/documents/specrend/には、波長を CIE コンポーネント (目の 3 種類の錐体センサーの出力にほぼ対応する) に変換する方法と、その方法がかなり詳細に説明されています。それらをRGB値に変換します(一部の波長には、典型的なRGB色域に対応するRGBがないという警告があります)。
または: CIE L*a*b* のようなさまざまな「知覚的に均一な色空間」があります (例: http://en.wikipedia.org/wiki/Lab_color_spaceを参照)。それらのいずれかを選択し、そのスペースで開始色と終了色を結ぶ直線に沿って同じ手順を実行し、RGB に変換できます。
ただし、どちらもアプリケーションにとってはやり過ぎである可能性が高く、単純で純粋に経験的なものよりもはるかに (または少しでも) 優れている明確な理由はありません。では、次のことを行ってみませんか。
- 開始色と終了色を選択します。簡単にするために、HSV 空間に S=1 と V=1 があるとします。それらを書き留めます。
- 投稿した色相の「スペクトル」に沿って見て、開始点と終了点のほぼ中間に見える色を見つけます。これをメモしてください。
- ここで再び二等分します。開始点と中間点の中間、および中間点と終了点の中間にある色を見つけます。
- 色相スケールを 8 または 16 の「知覚的に等しい」部分に分割するように、さらに 1 ~ 2 回繰り返します。
- RGB に変換し、それらをルックアップ テーブルに貼り付け、その間を線形補間します。
- 見栄えが良くなるまで、RGB 値を少し調整します。
これは完全にアドホックであり、原則はまったくありませんが、おそらくかなりうまく機能し、最終的なコードは基本的に簡単になります。
void compute_rgb(int * rp, int * gp, int * bp, int t) {
// t in the range 0..255 (for convenience)
int segment = t>>5; // 0..7
int delta = t&31;
int a=rgb_table[segment].r, b=rgb_table[segment+1].r;
*rp = a + ((delta*(b-a))>>5);
a=rgb_table[segment].g; b=rgb_table[segment+1].g;
*gp = a + ((delta*(b-a))>>5);
a=rgb_table[segment].b; b=rgb_table[segment+1].b;
*bp = a + ((delta*(b-a))>>5);
}
(使用可能なすべてのサイクルを保存することを気にしない場合は、コードをいくらか明確にすることができます)。
価値のあることとして、私の目は、約 (0)、40、60、90、150、180、240、270、(300) の色相値に分割点を配置しました。あなたのマイレージは異なる場合があります。