laws/blackbody-test.js
42 lines · in natura-src-1.0.0.zip as natura/laws/blackbody-test.js · a test
// blackbody-test.js -- prove the colour-of-temperature law against the known Planckian locus anchors, by
// RUNNING it and asserting on the NUMBERS (never by reasoning about the colour).
const BB = require('./blackbody.js');
let pass = 0, fail = 0;
const ok = (c, m) => { if (c) pass++; else { fail++; console.log(' FAIL: ' + m); } };
// --- the locus HUE: cool = red, hot = blue, with a white crossover near daylight ---
const ember = BB.colourOf(1200); // a cooling ember / lava
ok(ember[0] > ember[1] && ember[1] > ember[2], '1200K -> red>green>blue (a dull red heat) (' + ember + ')');
ok(ember[0] > 200 && ember[2] < 60, '1200K -> strongly red, almost no blue (' + ember + ')');
const bulb = BB.colourOf(2700); // an incandescent bulb -- warm white
ok(bulb[0] >= bulb[1] && bulb[1] > bulb[2], '2700K -> warm white (r>=g>b) (' + bulb + ')');
const sun = BB.colourOf(5800); // the Sun -- near neutral white
ok(Math.abs(sun[0] - sun[2]) < 55, '5800K -> near neutral (r ~ b) (' + sun + ')');
ok(sun[0] > 210 && sun[1] > 210 && sun[2] > 180, '5800K -> bright whitish (' + sun + ')');
const hot = BB.colourOf(20000); // a hot blue star
ok(hot[2] > hot[0], '20000K -> blue channel beats red (a blue star) (' + hot + ')');
// --- the red->blue CROSSOVER is monotone and lands in the daylight range ---
let cross = -1;
for (let T = 1000; T <= 20000; T += 250) { const c = BB.colourOf(T); if (c[2] >= c[0]) { cross = T; break; } }
ok(cross >= 5000 && cross <= 9000, 'red/blue crossover sits in the daylight range (~' + cross + 'K)');
// warmer is redder than cooler-of-the-hot-side: r/b ratio falls monotonically-ish with T
ok((BB.colourOf(2000)[0] / (BB.colourOf(2000)[2] + 1)) > (BB.colourOf(6500)[0] / (BB.colourOf(6500)[2] + 1)),
'a 2000K glow is far redder (higher r/b) than a 6500K one');
// --- Planck's law shape: at a fixed lambda, a hotter body radiates MORE; the visible peak shifts to shorter
// wavelengths as T rises (Wien) ---
ok(BB.planck(550, 6000) > BB.planck(550, 3000), 'hotter body radiates more at 550nm (Planck rises with T)');
function peakVis(T) { let bl = 380, bv = 0; for (let l = 380; l <= 720; l += 2) { const v = BB.planck(l, T); if (v > bv) { bv = v; bl = l; } } return bl; }
ok(peakVis(7000) < peakVis(3000), 'the visible peak shifts BLUEWARD as T rises (Wien) (' + peakVis(3000) + ' -> ' + peakVis(7000) + ')');
// --- determinism ---
const a = BB.colourOf(4200), b = BB.colourOf(4200);
ok(a[0] === b[0] && a[1] === b[1] && a[2] === b[2], 'deterministic');
console.log('\nblackbody: ' + pass + ' passed, ' + fail + ' failed');
if (fail) process.exit(1);