Índice de cores Star B-V para cor RGB aparente

Estou tentando converter uma estrelaÍndice de cores B-V para uma cor RGB aparente. Além de procurar tabelas e rampas coloridas, parece que não existe um algoritmo conhecido para fazer isso.

O que é um índice de cores B-V?

É um número que os astrônomos atribuem a uma estrela para indicar sua cor aparente. Estrelas quentes (baixo B-V) são azuis / roxas e estrelas frias (alto B-V) são vermelhas com aquelas estrelas brancas / laranja no meio.

Algoritmo inicialB-V para Kelvin

var t = 4600 * ((1 / ((0.92 * bv) + 1.7)) +(1 / ((0.92 * bv) + 0.62)) );
Kelvin para xyY

Se você modelar uma estrela como um corpo negro, poderá usar uma aproximação numérica doLócus planckiano para calcular as coordenadas xy (cromaticidade da 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,9)) / Math.pow(t,3)) + ((2.1070379 * Math.pow(10,6)) / Math.pow(t,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 a XYZ (Y = 1)

// 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;
XYZ para RGB

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;
Pergunta, questão

Eu executei esse algoritmo com os índices de cores B-V: 1.2, 1.0, 0.59, 0.0, -0.29. Isto é o que eu tenho como saída.

Por que recebi essa saída estranha?&nbsp;Estrelas quentes são azuladas, mas estrelas frias são marrom e não parece haver estrelas intermediárias em branco / laranja.

Atualizar

Seguindo um comentário deOzan, parecia que eu estava usando uma matriz errada para converter XYZ em RGB. Como sRGB é o espaço de cores padrão na Web (ou é?), Agora estou usando a matriz correta seguida por uma função de correção de gama (a = 0.055)

Agora eu recebo essa bela rampa de cores,

mas ainda não há vermelho / violeta nas extremidades.

Demo

Há também umviolino&nbsp;agora que você pode brincar.

Atualização 2

Se usar uma gama de 0,5 e estender o intervalo de índices de cores B-V para 4,7 a -0,5, fico vermelho em um extremo, mas ainda não violeta. Aqui está o atualizadoviolino.