http://www.fourmilab.ch/documents/specrend/有相当详细的描述如何将波长转换为 CIE 分量(大致对应于您眼睛中三种锥形传感器的输出),然后如何将它们转换为 RGB 值(警告某些波长在典型的 RGB 色域中没有 RGB 等效值)。
或者:有各种“感知上一致的色彩空间”,例如 CIE L*a*b*(参见例如http://en.wikipedia.org/wiki/Lab_color_space);您可以选择其中一个,沿着直线在该空间中连接您的起始颜色和结束颜色,然后转换为 RGB。
但是,对于您的应用程序来说,其中任何一个都可能是多余的,并且没有明显的理由为什么它们应该比更简单和纯粹凭经验的东西好得多——或任何——更好。那么为什么不做以下事情:
- 选择你的开始和结束颜色。为简单起见,假设它们在 HSV 空间中具有 S=1 和 V=1。记下它们。
- 查看您发布的色相“光谱”,找到一种看起来在您的起点和终点之间大约一半的颜色。记下这一点。
- 现在再次平分:在开始和中间之间找到颜色,在中间和结束之间找到颜色。
- 再重复一次或两次,这样您就可以将色调比例分成 8 或 16 个“感知上相等”的部分。
- 转换为 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) 的色调值上。你的旅费可能会改变。