我正在尝试将明星的 B-V color index转换成明显的RGB色彩.除了查看表格和颜色斜坡,似乎没有一个熟知的算法来做到这一点.
什么是B-V颜色指标?
这是一个数字天文学家分配给一个明星来表示它的明显的颜色.热星(低B-V)是蓝色/紫色和酷星(高B-V)是红色的,其间的白色/橙色星星之间.
初始算法
B-V到开尔文
var t = 4600 * ((1 / ((0.92 * bv) + 1.7)) +(1 / ((0.92 * bv) + 0.62)) );
开尔文到xyY
如果您将星型建模为黑体,则可以使用Planckian locus的数值近似来计算xy坐标(CIE色度)
// t to xyY var x,y = 0; if (t>=1667 && t<=4000) { x = ((-0.2661239 * Math.pow(10,9)) / Math.pow(t,3)) + ((-0.2343580 * Math.pow(10,6)) / Math.pow(t,2)) + ((0.8776956 * Math.pow(10,3)) / t) + 0.179910; } else if (t > 4000 && t <= 25000) { x = ((-3.0258469 * Math.pow(10,3)) + ((2.1070379 * Math.pow(10,2)) + ((0.2226347 * Math.pow(10,3)) / t) + 0.240390; } if (t >= 1667 && t <= 2222) { y = -1.1063814 * Math.pow(x,3) - 1.34811020 * Math.pow(x,2) + 2.18555832 * x - 0.20219683; } else if (t > 2222 && t <= 4000) { y = -0.9549476 * Math.pow(x,3) - 1.37418593 * Math.pow(x,2) + 2.09137015 * x - 0.16748867; } else if (t > 4000 && t <= 25000) { y = 3.0817580 * Math.pow(x,3) - 5.87338670 * Math.pow(x,2) + 3.75112997 * x - 0.37001483; }
// xyY to XYZ,Y = 1 var Y = (y == 0)? 0 : 1; var X = (y == 0)? 0 : (x * Y) / y; var Z = (y == 0)? 0 : ((1 - x - y) * Y) / y;
var r = 0.41847 * X - 0.15866 * Y - 0.082835 * Z; var g = -0.091169 * X + 0.25243 * Y + 0.015708 * Z; var b = 0.00092090 * X - 0.0025498 * Y + 0.17860 * Z;
题
我运行这个算法与B-V颜色索引:1.2,1.0,0.59,0.0,-0.29.这是我得到的输出.
为什么我得到这个奇怪的输出?热的星星是蓝色的,但是冷的星星是棕色的,似乎并不是白色/橙色的中间星星.
更新
在Ozan发表评论后,似乎我正在使用一个错误的矩阵将XYZ转换为RGB.由于sRGB是网络上的默认颜色空间(或者是?),我现在使用正确的矩阵,后跟伽马校正函数(a = 0.055).
我现在得到这个漂亮的颜色斜坡,
但在四肢仍然没有红色/紫色.
演示
现在还有一个fiddle可以玩.
更新2
如果使用0.5的伽玛,并将B-V颜色指数的范围从4.7增加到-0.5,我会在一个极端变红,但仍然没有紫色.这是fiddle更新.
解决方法
我使用插图插补.几年前,我在这个地方找到了这个表:
type r g b rrggbb B-V O5(V) 155 176 255 #9bb0ff -0.32 blue O6(V) 162 184 255 #a2b8ff O7(V) 157 177 255 #9db1ff O8(V) 157 177 255 #9db1ff O9(V) 154 178 255 #9ab2ff O9.5(V) 164 186 255 #a4baff B0(V) 156 178 255 #9cb2ff B0.5(V) 167 188 255 #a7bcff B1(V) 160 182 255 #a0b6ff B2(V) 160 180 255 #a0b4ff B3(V) 165 185 255 #a5b9ff B4(V) 164 184 255 #a4b8ff B5(V) 170 191 255 #aabfff B6(V) 172 189 255 #acbdff B7(V) 173 191 255 #adbfff B8(V) 177 195 255 #b1c3ff B9(V) 181 198 255 #b5c6ff A0(V) 185 201 255 #b9c9ff 0.00 White A1(V) 181 199 255 #b5c7ff A2(V) 187 203 255 #bbcbff A3(V) 191 207 255 #bfcfff A5(V) 202 215 255 #cad7ff A6(V) 199 212 255 #c7d4ff A7(V) 200 213 255 #c8d5ff A8(V) 213 222 255 #d5deff A9(V) 219 224 255 #dbe0ff F0(V) 224 229 255 #e0e5ff 0.31 yellowish F2(V) 236 239 255 #ecefff F4(V) 224 226 255 #e0e2ff F5(V) 248 247 255 #f8f7ff F6(V) 244 241 255 #f4f1ff F7(V) 246 243 255 #f6f3ff 0.50 F8(V) 255 247 252 #fff7fc F9(V) 255 247 252 #fff7fc G0(V) 255 248 252 #fff8fc 0.59 Yellow G1(V) 255 247 248 #fff7f8 G2(V) 255 245 242 #fff5f2 G4(V) 255 241 229 #fff1e5 G5(V) 255 244 234 #fff4ea G6(V) 255 244 235 #fff4eb G7(V) 255 244 235 #fff4eb G8(V) 255 237 222 #ffedde G9(V) 255 239 221 #ffefdd K0(V) 255 238 221 #fFeedd 0.82 Orange K1(V) 255 224 188 #ffe0bc K2(V) 255 227 196 #ffe3c4 K3(V) 255 222 195 #ffdec3 K4(V) 255 216 181 #ffd8b5 K5(V) 255 210 161 #ffd2a1 K7(V) 255 199 142 #ffc78e K8(V) 255 209 174 #ffd1ae M0(V) 255 195 139 #ffc38b 1.41 red M1(V) 255 204 142 #ffcc8e M2(V) 255 196 131 #ffc483 M3(V) 255 206 129 #ffce81 M4(V) 255 201 127 #ffc97f M5(V) 255 204 111 #ffcc6f M6(V) 255 195 112 #ffc370 M8(V) 255 198 109 #ffc66d 2.00
>在使用前仅插入缺失的B-V索引(线性或更好)
然后使用线性插值得到RGB = f(B-V);
>找到表中最近的两行并在它们之间插值…
[edit1] heh只是偶然遇到了this(我之前提到的原始信息)
[edit2]这里是我的近似没有任何XYZ的东西
因此,BV指数来自< -0.4,2.0>
这里是我的(C)代码转换:
//--------------------------------------------------------------------------- void bv2rgb(double &r,double &g,double &b,double bv) // RGB <0,1> <- BV <-0.4,+2.0> [-] { double t; r=0.0; g=0.0; b=0.0; if (bv<-0.4) bv=-0.4; if (bv> 2.0) bv= 2.0; if ((bv>=-0.40)&&(bv<0.00)) { t=(bv+0.40)/(0.00+0.40); r=0.61+(0.11*t)+(0.1*t*t); } else if ((bv>= 0.00)&&(bv<0.40)) { t=(bv-0.00)/(0.40-0.00); r=0.83+(0.17*t) ; } else if ((bv>= 0.40)&&(bv<2.10)) { t=(bv-0.40)/(2.10-0.40); r=1.00 ; } if ((bv>=-0.40)&&(bv<0.00)) { t=(bv+0.40)/(0.00+0.40); g=0.70+(0.07*t)+(0.1*t*t); } else if ((bv>= 0.00)&&(bv<0.40)) { t=(bv-0.00)/(0.40-0.00); g=0.87+(0.11*t) ; } else if ((bv>= 0.40)&&(bv<1.60)) { t=(bv-0.40)/(1.60-0.40); g=0.98-(0.16*t) ; } else if ((bv>= 1.60)&&(bv<2.00)) { t=(bv-1.60)/(2.00-1.60); g=0.82 -(0.5*t*t); } if ((bv>=-0.40)&&(bv<0.40)) { t=(bv+0.40)/(0.40+0.40); b=1.00 ; } else if ((bv>= 0.40)&&(bv<1.50)) { t=(bv-0.40)/(1.50-0.40); b=1.00-(0.47*t)+(0.1*t*t); } else if ((bv>= 1.50)&&(bv<1.94)) { t=(bv-1.50)/(1.94-1.50); b=0.63 -(0.6*t*t); } } //---------------------------------------------------------------------------
[笔记]
这种BV颜色是定义温度照明的黑体,因此这表示从空间观看的星形颜色.对于视觉正确的颜色,你必须添加大气散射效果我们的气氛!例如我们的太阳是“白色”,但是在光散射之后,颜色从红色(近地平线)到黄色(靠近天底…中午)