Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Black body temperature to color converter
;; Better interpolation functions for calculating temperature colors
;; Reference: http://www.zombieprototypes.com/?p=210
;; Data: http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html
;; use fastmath and clojure2d libraries
(ns black-body.temperature
(:require [fastmath.core :as m]
[fastmath.interpolation :as i]
[clojure2d.color :as c]
[fastmath.optimization :as o]))
(set! *warn-on-reflection* true)
(set! *unchecked-math* :warn-on-boxed)
(m/use-primitive-operators)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(def red [[6600 0.9917] [6700 0.9696] [6800 0.9488] [6900 0.9290] [7000 0.9102] [7100 0.8923] [7200 0.8753] [7300 0.8591]
[7400 0.8437] [7500 0.8289] [7600 0.8149] [7700 0.8014] [7800 0.7885] [7900 0.7762] [8000 0.7644] [8100 0.7531]
[8200 0.7423] [8300 0.7319] [8400 0.7219] [8500 0.7123] [8600 0.7030] [8700 0.6941] [8800 0.6856] [8900 0.6773]
[9000 0.6693] [9100 0.6617] [9200 0.6543] [9300 0.6471] [9400 0.6402] [9500 0.6335] [9600 0.6271] [9700 0.6208]
[9800 0.6148] [9900 0.6089] [10000 0.6033] [10100 0.5978] [10200 0.5925] [10300 0.5873] [10400 0.5823] [10500 0.5774]
[10600 0.5727] [10700 0.5681] [10800 0.5637] [10900 0.5593] [11000 0.5551] [11100 0.5510] [11200 0.5470] [11300 0.5432]
[11400 0.5394] [11500 0.5357] [11600 0.5322] [11700 0.5287] [11800 0.5253] [11900 0.5220] [12000 0.5187] [12100 0.5156]
[12200 0.5125] [12300 0.5095] [12400 0.5066] [12500 0.5037] [12600 0.5009] [12700 0.4982] [12800 0.4955] [12900 0.4929]
[13000 0.4904] [13100 0.4879] [13200 0.4854] [13300 0.4831] [13400 0.4807] [13500 0.4785] [13600 0.4762] [13700 0.4740]
[13800 0.4719] [13900 0.4698] [14000 0.4677] [14100 0.4657] [14200 0.4638] [14300 0.4618] [14400 0.4599] [14500 0.4581]
[14600 0.4563] [14700 0.4545] [14800 0.4527] [14900 0.4510] [15000 0.4493] [15100 0.4477] [15200 0.4460] [15300 0.4445]
[15400 0.4429] [15500 0.4413] [15600 0.4398] [15700 0.4384] [15800 0.4369] [15900 0.4355] [16000 0.4341] [16100 0.4327]
[16200 0.4313] [16300 0.4300] [16400 0.4287] [16500 0.4274] [16600 0.4261] [16700 0.4249] [16800 0.4236] [16900 0.4224]
[17000 0.4212] [17100 0.4201] [17200 0.4189] [17300 0.4178] [17400 0.4167] [17500 0.4156] [17600 0.4145] [17700 0.4134]
[17800 0.4124] [17900 0.4113] [18000 0.4103] [18100 0.4093] [18200 0.4083] [18300 0.4074] [18400 0.4064] [18500 0.4055]
[18600 0.4045] [18700 0.4036] [18800 0.4027] [18900 0.4018] [19000 0.4009] [19100 0.4001] [19200 0.3992] [19300 0.3984]
[19400 0.3975] [19500 0.3967] [19600 0.3959] [19700 0.3951] [19800 0.3943] [19900 0.3935] [20000 0.3928] [20100 0.3920]
[20200 0.3913] [20300 0.3905] [20400 0.3898] [20500 0.3891] [20600 0.3884] [20700 0.3877] [20800 0.3870] [20900 0.3863]
[21000 0.3856] [21100 0.3850] [21200 0.3843] [21300 0.3836] [21400 0.3830] [21500 0.3824] [21600 0.3817] [21700 0.3811]
[21800 0.3805] [21900 0.3799] [22000 0.3793] [22100 0.3787] [22200 0.3781] [22300 0.3776] [22400 0.3770] [22500 0.3764]
[22600 0.3759] [22700 0.3753] [22800 0.3748] [22900 0.3742] [23000 0.3737] [23100 0.3732] [23200 0.3726] [23300 0.3721]
[23400 0.3716] [23500 0.3711] [23600 0.3706] [23700 0.3701] [23800 0.3696] [23900 0.3692] [24000 0.3687] [24100 0.3682]
[24200 0.3677] [24300 0.3673] [24400 0.3668] [24500 0.3664] [24600 0.3659] [24700 0.3655] [24800 0.3650] [24900 0.3646]
[25000 0.3642] [25100 0.3637] [25200 0.3633] [25300 0.3629] [25400 0.3625] [25500 0.3621] [25600 0.3617] [25700 0.3613]
[25800 0.3609] [25900 0.3605] [26000 0.3601] [26100 0.3597] [26200 0.3593] [26300 0.3589] [26400 0.3586] [26500 0.3582]
[26600 0.3578] [26700 0.3575] [26800 0.3571] [26900 0.3567] [27000 0.3564] [27100 0.3560] [27200 0.3557] [27300 0.3553]
[27400 0.3550] [27500 0.3546] [27600 0.3543] [27700 0.3540] [27800 0.3536] [27900 0.3533] [28000 0.3530] [28100 0.3527]
[28200 0.3524] [28300 0.3520] [28400 0.3517] [28500 0.3514] [28600 0.3511] [28700 0.3508] [28800 0.3505] [28900 0.3502]
[29000 0.3499] [29100 0.3496] [29200 0.3493] [29300 0.3490] [29400 0.3487] [29500 0.3485] [29600 0.3482] [29700 0.3479]
[29800 0.3476] [29900 0.3473] [30000 0.3471] [30100 0.3468] [30200 0.3465] [30300 0.3463] [30400 0.3460] [30500 0.3457]
[30600 0.3455] [30700 0.3452] [30800 0.3450] [30900 0.3447] [31000 0.3444] [31100 0.3442] [31200 0.3439] [31300 0.3437]
[31400 0.3435] [31500 0.3432] [31600 0.3430] [31700 0.3427] [31800 0.3425] [31900 0.3423] [32000 0.3420] [32100 0.3418]
[32200 0.3416] [32300 0.3413] [32400 0.3411] [32500 0.3409] [32600 0.3407] [32700 0.3404] [32800 0.3402] [32900 0.3400]
[33000 0.3398] [33100 0.3396] [33200 0.3393] [33300 0.3391] [33400 0.3389] [33500 0.3387] [33600 0.3385] [33700 0.3383]
[33800 0.3381] [33900 0.3379] [34000 0.3377] [34100 0.3375] [34200 0.3373] [34300 0.3371] [34400 0.3369] [34500 0.3367]
[34600 0.3365] [34700 0.3363] [34800 0.3361] [34900 0.3359] [35000 0.3357] [35100 0.3356] [35200 0.3354] [35300 0.3352]
[35400 0.3350] [35500 0.3348] [35600 0.3346] [35700 0.3345] [35800 0.3343] [35900 0.3341] [36000 0.3339] [36100 0.3338]
[36200 0.3336] [36300 0.3334] [36400 0.3332] [36500 0.3331] [36600 0.3329] [36700 0.3327] [36800 0.3326] [36900 0.3324]
[37000 0.3322] [37100 0.3321] [37200 0.3319] [37300 0.3317] [37400 0.3316] [37500 0.3314] [37600 0.3313] [37700 0.3311]
[37800 0.3309] [37900 0.3308] [38000 0.3306] [38100 0.3305] [38200 0.3303] [38300 0.3302] [38400 0.3300] [38500 0.3299]
[38600 0.3297] [38700 0.3296] [38800 0.3294] [38900 0.3293] [39000 0.3291] [39100 0.3290] [39200 0.3288] [39300 0.3287]
[39400 0.3286] [39500 0.3284] [39600 0.3283] [39700 0.3281] [39800 0.3280] [39900 0.3279] [40000 0.3277]])
(def rgb-red [[6600 254] [6700 252] [6800 249] [6900 247] [7000 245] [7100 243] [7200 240] [7300 239]
[7400 237] [7500 235] [7600 233] [7700 231] [7800 230] [7900 228] [8000 227] [8100 225]
[8200 224] [8300 222] [8400 221] [8500 220] [8600 218] [8700 217] [8800 216] [8900 215]
[9000 214] [9100 212] [9200 211] [9300 210] [9400 209] [9500 208] [9600 207] [9700 207]
[9800 206] [9900 205] [10000 204] [10100 203] [10200 202] [10300 201] [10400 201] [10500 200]
[10600 199] [10700 199] [10800 198] [10900 197] [11000 196] [11100 196] [11200 195] [11300 195]
[11400 194] [11500 193] [11600 193] [11700 192] [11800 192] [11900 191] [12000 191] [12100 190]
[12200 190] [12300 189] [12400 189] [12500 188] [12600 188] [12700 187] [12800 187] [12900 186]
[13000 186] [13100 185] [13200 185] [13300 185] [13400 184] [13500 184] [13600 183] [13700 183]
[13800 183] [13900 182] [14000 182] [14100 182] [14200 181] [14300 181] [14400 181] [14500 180]
[14600 180] [14700 180] [14800 179] [14900 179] [15000 179] [15100 178] [15200 178] [15300 178]
[15400 178] [15500 177] [15600 177] [15700 177] [15800 177] [15900 176] [16000 176] [16100 176]
[16200 175] [16300 175] [16400 175] [16500 175] [16600 175] [16700 174] [16800 174] [16900 174]
[17000 174] [17100 173] [17200 173] [17300 173] [17400 173] [17500 173] [17600 172] [17700 172]
[17800 172] [17900 172] [18000 172] [18100 171] [18200 171] [18300 171] [18400 171] [18500 171]
[18600 170] [18700 170] [18800 170] [18900 170] [19000 170] [19100 170] [19200 169] [19300 169]
[19400 169] [19500 169] [19600 169] [19700 169] [19800 169] [19900 168] [20000 168] [20100 168]
[20200 168] [20300 168] [20400 168] [20500 168] [20600 167] [20700 167] [20800 167] [20900 167]
[21000 167] [21100 167] [21200 167] [21300 166] [21400 166] [21500 166] [21600 166] [21700 166]
[21800 166] [21900 166] [22000 166] [22100 165] [22200 165] [22300 165] [22400 165] [22500 165]
[22600 165] [22700 165] [22800 165] [22900 165] [23000 164] [23100 164] [23200 164] [23300 164]
[23400 164] [23500 164] [23600 164] [23700 164] [23800 164] [23900 164] [24000 163] [24100 163]
[24200 163] [24300 163] [24400 163] [24500 163] [24600 163] [24700 163] [24800 163] [24900 163]
[25000 163] [25100 162] [25200 162] [25300 162] [25400 162] [25500 162] [25600 162] [25700 162]
[25800 162] [25900 162] [26000 162] [26100 162] [26200 162] [26300 162] [26400 161] [26500 161]
[26600 161] [26700 161] [26800 161] [26900 161] [27000 161] [27100 161] [27200 161] [27300 161]
[27400 161] [27500 161] [27600 161] [27700 161] [27800 160] [27900 160] [28000 160] [28100 160]
[28200 160] [28300 160] [28400 160] [28500 160] [28600 160] [28700 160] [28800 160] [28900 160]
[29000 160] [29100 160] [29200 160] [29300 159] [29400 159] [29500 159] [29600 159] [29700 159]
[29800 159] [29900 159] [30000 159] [30100 159] [30200 159] [30300 159] [30400 159] [30500 159]
[30600 159] [30700 159] [30800 159] [30900 159] [31000 159] [31100 158] [31200 158] [31300 158]
[31400 158] [31500 158] [31600 158] [31700 158] [31800 158] [31900 158] [32000 158] [32100 158]
[32200 158] [32300 158] [32400 158] [32500 158] [32600 158] [32700 158] [32800 158] [32900 158]
[33000 158] [33100 158] [33200 157] [33300 157] [33400 157] [33500 157] [33600 157] [33700 157]
[33800 157] [33900 157] [34000 157] [34100 157] [34200 157] [34300 157] [34400 157] [34500 157]
[34600 157] [34700 157] [34800 157] [34900 157] [35000 157] [35100 157] [35200 157] [35300 157]
[35400 157] [35500 157] [35600 156] [35700 156] [35800 156] [35900 156] [36000 156] [36100 156]
[36200 156] [36300 156] [36400 156] [36500 156] [36600 156] [36700 156] [36800 156] [36900 156]
[37000 156] [37100 156] [37200 156] [37300 156] [37400 156] [37500 156] [37600 156] [37700 156]
[37800 156] [37900 156] [38000 156] [38100 156] [38200 156] [38300 156] [38400 155] [38500 155]
[38600 155] [38700 155] [38800 155] [38900 155] [39000 155] [39100 155] [39200 155] [39300 155]
[39400 155] [39500 155] [39600 155] [39700 155] [39800 155] [39900 155] [40000 155]])
(def green1 [[1000 0.0401] [1100 0.0631] [1200 0.0860] [1300 0.1085] [1400 0.1303] [1500 0.1515] [1600 0.1718] [1700 0.1912]
[1800 0.2097] [1900 0.2272] [2000 0.2484] [2100 0.2709] [2200 0.2930] [2300 0.3149] [2400 0.3364] [2500 0.3577]
[2600 0.3786] [2700 0.3992] [2800 0.4195] [2900 0.4394] [3000 0.4589] [3100 0.4781] [3200 0.4970] [3300 0.5155]
[3400 0.5336] [3500 0.5515] [3600 0.5689] [3700 0.5860] [3800 0.6028] [3900 0.6193] [4000 0.6354] [4100 0.6511]
[4200 0.6666] [4300 0.6817] [4400 0.6966] [4500 0.7111] [4600 0.7253] [4700 0.7392] [4800 0.7528] [4900 0.7661]
[5000 0.7792] [5100 0.7919] [5200 0.8044] [5300 0.8167] [5400 0.8286] [5500 0.8403] [5600 0.8518] [5700 0.8630]
[5800 0.8740] [5900 0.8847] [6000 0.8952] [6100 0.9055] [6200 0.9156] [6300 0.9254] [6400 0.9351] [6500 0.9445]])
(def rgb-green1 [[1000 56] [1100 71] [1200 83] [1300 93] [1400 101] [1500 109] [1600 115] [1700 121]
[1800 126] [1900 131] [2000 137] [2100 142] [2200 147] [2300 152] [2400 157] [2500 161]
[2600 165] [2700 169] [2800 173] [2900 177] [3000 180] [3100 184] [3200 187] [3300 190]
[3400 193] [3500 196] [3600 199] [3700 201] [3800 204] [3900 206] [4000 209] [4100 211]
[4200 213] [4300 215] [4400 217] [4500 219] [4600 221] [4700 223] [4800 225] [4900 227]
[5000 228] [5100 230] [5200 232] [5300 233] [5400 235] [5500 236] [5600 238] [5700 239]
[5800 240] [5900 242] [6000 243] [6100 244] [6200 245] [6300 246] [6400 248] [6500 249]])
(def green2 [[6600 0.9458] [6700 0.9336] [6800 0.9219] [6900 0.9107] [7000 0.9000] [7100 0.8897] [7200 0.8799]
[7300 0.8704] [7400 0.8614] [7500 0.8527] [7600 0.8443] [7700 0.8363] [7800 0.8285] [7900 0.8211]
[8000 0.8139] [8100 0.8069] [8200 0.8002] [8300 0.7938] [8400 0.7875] [8500 0.7815] [8600 0.7757]
[8700 0.7700] [8800 0.7645] [8900 0.7593] [9000 0.7541] [9100 0.7492] [9200 0.7444] [9300 0.7397]
[9400 0.7352] [9500 0.7308] [9600 0.7265] [9700 0.7224] [9800 0.7183] [9900 0.7144] [10000 0.7106]
[10100 0.7069] [10200 0.7033] [10300 0.6998] [10400 0.6964] [10500 0.6930] [10600 0.6898] [10700 0.6866]
[10800 0.6836] [10900 0.6806] [11000 0.6776] [11100 0.6748] [11200 0.6720] [11300 0.6693] [11400 0.6666]
[11500 0.6640] [11600 0.6615] [11700 0.6590] [11800 0.6566] [11900 0.6542] [12000 0.6519] [12100 0.6497]
[12200 0.6474] [12300 0.6453] [12400 0.6432] [12500 0.6411] [12600 0.6391] [12700 0.6371] [12800 0.6351]
[12900 0.6332] [13000 0.6314] [13100 0.6295] [13200 0.6277] [13300 0.6260] [13400 0.6243] [13500 0.6226]
[13600 0.6209] [13700 0.6193] [13800 0.6177] [13900 0.6161] [14000 0.6146] [14100 0.6131] [14200 0.6116]
[14300 0.6102] [14400 0.6087] [14500 0.6073] [14600 0.6060] [14700 0.6046] [14800 0.6033] [14900 0.6020]
[15000 0.6007] [15100 0.5994] [15200 0.5982] [15300 0.5970] [15400 0.5958] [15500 0.5946] [15600 0.5935]
[15700 0.5923] [15800 0.5912] [15900 0.5901] [16000 0.5890] [16100 0.5879] [16200 0.5869] [16300 0.5859]
[16400 0.5848] [16500 0.5838] [16600 0.5829] [16700 0.5819] [16800 0.5809] [16900 0.5800] [17000 0.5791]
[17100 0.5781] [17200 0.5772] [17300 0.5763] [17400 0.5755] [17500 0.5746] [17600 0.5738] [17700 0.5729]
[17800 0.5721] [17900 0.5713] [18000 0.5705] [18100 0.5697] [18200 0.5689] [18300 0.5681] [18400 0.5674]
[18500 0.5666] [18600 0.5659] [18700 0.5652] [18800 0.5644] [18900 0.5637] [19000 0.5630] [19100 0.5623]
[19200 0.5616] [19300 0.5610] [19400 0.5603] [19500 0.5596] [19600 0.5590] [19700 0.5584] [19800 0.5577]
[19900 0.5571] [20000 0.5565] [20100 0.5559] [20200 0.5553] [20300 0.5547] [20400 0.5541] [20500 0.5535]
[20600 0.5529] [20700 0.5524] [20800 0.5518] [20900 0.5513] [21000 0.5507] [21100 0.5502] [21200 0.5496]
[21300 0.5491] [21400 0.5486] [21500 0.5481] [21600 0.5476] [21700 0.5471] [21800 0.5466] [21900 0.5461]
[22000 0.5456] [22100 0.5451] [22200 0.5446] [22300 0.5441] [22400 0.5437] [22500 0.5432] [22600 0.5428]
[22700 0.5423] [22800 0.5419] [22900 0.5414] [23000 0.5410] [23100 0.5405] [23200 0.5401] [23300 0.5397]
[23400 0.5393] [23500 0.5389] [23600 0.5384] [23700 0.5380] [23800 0.5376] [23900 0.5372] [24000 0.5368]
[24100 0.5365] [24200 0.5361] [24300 0.5357] [24400 0.5353] [24500 0.5349] [24600 0.5346] [24700 0.5342]
[24800 0.5338] [24900 0.5335] [25000 0.5331] [25100 0.5328] [25200 0.5324] [25300 0.5321] [25400 0.5317]
[25500 0.5314] [25600 0.5310] [25700 0.5307] [25800 0.5304] [25900 0.5300] [26000 0.5297] [26100 0.5294]
[26200 0.5291] [26300 0.5288] [26400 0.5284] [26500 0.5281] [26600 0.5278] [26700 0.5275] [26800 0.5272]
[26900 0.5269] [27000 0.5266] [27100 0.5263] [27200 0.5260] [27300 0.5257] [27400 0.5255] [27500 0.5252]
[27600 0.5249] [27700 0.5246] [27800 0.5243] [27900 0.5241] [28000 0.5238] [28100 0.5235] [28200 0.5232]
[28300 0.5230] [28400 0.5227] [28500 0.5225] [28600 0.5222] [28700 0.5219] [28800 0.5217] [28900 0.5214]
[29000 0.5212] [29100 0.5209] [29200 0.5207] [29300 0.5204] [29400 0.5202] [29500 0.5200] [29600 0.5197]
[29700 0.5195] [29800 0.5192] [29900 0.5190] [30000 0.5188] [30100 0.5186] [30200 0.5183] [30300 0.5181]
[30400 0.5179] [30500 0.5177] [30600 0.5174] [30700 0.5172] [30800 0.5170] [30900 0.5168] [31000 0.5166]
[31100 0.5164] [31200 0.5161] [31300 0.5159] [31400 0.5157] [31500 0.5155] [31600 0.5153] [31700 0.5151]
[31800 0.5149] [31900 0.5147] [32000 0.5145] [32100 0.5143] [32200 0.5141] [32300 0.5139] [32400 0.5137]
[32500 0.5135] [32600 0.5133] [32700 0.5132] [32800 0.5130] [32900 0.5128] [33000 0.5126] [33100 0.5124]
[33200 0.5122] [33300 0.5120] [33400 0.5119] [33500 0.5117] [33600 0.5115] [33700 0.5113] [33800 0.5112]
[33900 0.5110] [34000 0.5108] [34100 0.5106] [34200 0.5105] [34300 0.5103] [34400 0.5101] [34500 0.5100]
[34600 0.5098] [34700 0.5096] [34800 0.5095] [34900 0.5093] [35000 0.5091] [35100 0.5090] [35200 0.5088]
[35300 0.5087] [35400 0.5085] [35500 0.5084] [35600 0.5082] [35700 0.5080] [35800 0.5079] [35900 0.5077]
[36000 0.5076] [36100 0.5074] [36200 0.5073] [36300 0.5071] [36400 0.5070] [36500 0.5068] [36600 0.5067]
[36700 0.5066] [36800 0.5064] [36900 0.5063] [37000 0.5061] [37100 0.5060] [37200 0.5058] [37300 0.5057]
[37400 0.5056] [37500 0.5054] [37600 0.5053] [37700 0.5052] [37800 0.5050] [37900 0.5049] [38000 0.5048]
[38100 0.5046] [38200 0.5045] [38300 0.5044] [38400 0.5042] [38500 0.5041] [38600 0.5040] [38700 0.5038]
[38800 0.5037] [38900 0.5036] [39000 0.5035] [39100 0.5033] [39200 0.5032] [39300 0.5031] [39400 0.5030]
[39500 0.5028] [39600 0.5027] [39700 0.5026] [39800 0.5025] [39900 0.5024] [40000 0.5022]])
(def rgb-green2 [[6600 249] [6700 247] [6800 246] [6900 245] [7000 243] [7100 242] [7200 241] [7300 240]
[7400 239] [7500 238] [7600 237] [7700 236] [7800 235] [7900 234] [8000 233] [8100 232]
[8200 231] [8300 230] [8400 230] [8500 229] [8600 228] [8700 227] [8800 227] [8900 226]
[9000 225] [9100 225] [9200 224] [9300 223] [9400 223] [9500 222] [9600 221] [9700 221]
[9800 220] [9900 220] [10000 219] [10100 219] [10200 218] [10300 218] [10400 217] [10500 217]
[10600 216] [10700 216] [10800 216] [10900 215] [11000 215] [11100 214] [11200 214] [11300 214]
[11400 213] [11500 213] [11600 212] [11700 212] [11800 212] [11900 211] [12000 211] [12100 211]
[12200 210] [12300 210] [12400 210] [12500 210] [12600 209] [12700 209] [12800 209] [12900 208]
[13000 208] [13100 208] [13200 208] [13300 207] [13400 207] [13500 207] [13600 207] [13700 206]
[13800 206] [13900 206] [14000 206] [14100 205] [14200 205] [14300 205] [14400 205] [14500 205]
[14600 204] [14700 204] [14800 204] [14900 204] [15000 204] [15100 203] [15200 203] [15300 203]
[15400 203] [15500 203] [15600 202] [15700 202] [15800 202] [15900 202] [16000 202] [16100 202]
[16200 201] [16300 201] [16400 201] [16500 201] [16600 201] [16700 201] [16800 201] [16900 200]
[17000 200] [17100 200] [17200 200] [17300 200] [17400 200] [17500 200] [17600 199] [17700 199]
[17800 199] [17900 199] [18000 199] [18100 199] [18200 199] [18300 199] [18400 198] [18500 198]
[18600 198] [18700 198] [18800 198] [18900 198] [19000 198] [19100 198] [19200 198] [19300 197]
[19400 197] [19500 197] [19600 197] [19700 197] [19800 197] [19900 197] [20000 197] [20100 197]
[20200 197] [20300 196] [20400 196] [20500 196] [20600 196] [20700 196] [20800 196] [20900 196]
[21000 196] [21100 196] [21200 196] [21300 196] [21400 195] [21500 195] [21600 195] [21700 195]
[21800 195] [21900 195] [22000 195] [22100 195] [22200 195] [22300 195] [22400 195] [22500 195]
[22600 195] [22700 194] [22800 194] [22900 194] [23000 194] [23100 194] [23200 194] [23300 194]
[23400 194] [23500 194] [23600 194] [23700 194] [23800 194] [23900 194] [24000 194] [24100 194]
[24200 193] [24300 193] [24400 193] [24500 193] [24600 193] [24700 193] [24800 193] [24900 193]
[25000 193] [25100 193] [25200 193] [25300 193] [25400 193] [25500 193] [25600 193] [25700 193]
[25800 193] [25900 192] [26000 192] [26100 192] [26200 192] [26300 192] [26400 192] [26500 192]
[26600 192] [26700 192] [26800 192] [26900 192] [27000 192] [27100 192] [27200 192] [27300 192]
[27400 192] [27500 192] [27600 192] [27700 192] [27800 192] [27900 192] [28000 191] [28100 191]
[28200 191] [28300 191] [28400 191] [28500 191] [28600 191] [28700 191] [28800 191] [28900 191]
[29000 191] [29100 191] [29200 191] [29300 191] [29400 191] [29500 191] [29600 191] [29700 191]
[29800 191] [29900 191] [30000 191] [30100 191] [30200 191] [30300 191] [30400 190] [30500 190]
[30600 190] [30700 190] [30800 190] [30900 190] [31000 190] [31100 190] [31200 190] [31300 190]
[31400 190] [31500 190] [31600 190] [31700 190] [31800 190] [31900 190] [32000 190] [32100 190]
[32200 190] [32300 190] [32400 190] [32500 190] [32600 190] [32700 190] [32800 190] [32900 190]
[33000 190] [33100 190] [33200 190] [33300 190] [33400 189] [33500 189] [33600 189] [33700 189]
[33800 189] [33900 189] [34000 189] [34100 189] [34200 189] [34300 189] [34400 189] [34500 189]
[34600 189] [34700 189] [34800 189] [34900 189] [35000 189] [35100 189] [35200 189] [35300 189]
[35400 189] [35500 189] [35600 189] [35700 189] [35800 189] [35900 189] [36000 189] [36100 189]
[36200 189] [36300 189] [36400 189] [36500 189] [36600 189] [36700 189] [36800 189] [36900 189]
[37000 189] [37100 189] [37200 188] [37300 188] [37400 188] [37500 188] [37600 188] [37700 188]
[37800 188] [37900 188] [38000 188] [38100 188] [38200 188] [38300 188] [38400 188] [38500 188]
[38600 188] [38700 188] [38800 188] [38900 188] [39000 188] [39100 188] [39200 188] [39300 188]
[39400 188] [39500 188] [39600 188] [39700 188] [39800 188] [39900 188] [40000 188]])
(def rgb-green (concat rgb-green1 rgb-green2))
(def blue [[2000 0.0061] [2100 0.0153] [2200 0.0257] [2300 0.0373] [2400 0.0501] [2500 0.0640] [2600 0.0790]
[2700 0.0950] [2800 0.1119] [2900 0.1297] [3000 0.1483] [3100 0.1677] [3200 0.1879] [3300 0.2087]
[3400 0.2301] [3500 0.2520] [3600 0.2745] [3700 0.2974] [3800 0.3207] [3900 0.3444] [4000 0.3684]
[4100 0.3927] [4200 0.4172] [4300 0.4419] [4400 0.4668] [4500 0.4919] [4600 0.5170] [4700 0.5422]
[4800 0.5675] [4900 0.5928] [5000 0.6180] [5100 0.6433] [5200 0.6685] [5300 0.6937] [5400 0.7187]
[5500 0.7437] [5600 0.7686] [5700 0.7933] [5800 0.8179] [5900 0.8424] [6000 0.8666] [6100 0.8907]
[6200 0.9147] [6300 0.9384] [6400 0.9619] [6500 0.9853]])
(def rgb-blue [[2000 18] [2100 33] [2200 44] [2300 54] [2400 63] [2500 72] [2600 79]
[2700 87] [2800 94] [2900 101] [3000 107] [3100 114] [3200 120] [3300 126]
[3400 132] [3500 137] [3600 143] [3700 148] [3800 153] [3900 159] [4000 163]
[4100 168] [4200 173] [4300 177] [4400 182] [4500 186] [4600 190] [4700 194]
[4800 198] [4900 202] [5000 206] [5100 210] [5200 213] [5300 217] [5400 220]
[5500 224] [5600 227] [5700 230] [5800 233] [5900 236] [6000 239] [6100 242]
[6200 245] [6300 248] [6400 251] [6500 253]])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn model1
[a b c d e]
(let [aa (double a)
bb (double b)
cc (double c)
dd (double d)
ee (double e)]
(fn ^double [^double k]
(let [kk (* 0.0001 k)
res (+ aa (* bb (m/pow (+ ee kk) cc)) (* dd (m/ln kk)))]
(if (m/nan? res) ##Inf res)))))
(defn model2
[a b c d e]
(let [aa (double a)
bb (double b)
cc (double c)
dd (double d)
ee (double e)]
(fn ^double [^double k]
(let [kk (* 0.0001 k)
eekk (+ ee kk)
res (+ aa (* bb eekk eekk eekk (m/exp (* cc eekk))) (* dd (m/ln kk)))]
(if (m/nan? res) ##Inf res)))))
(defn target
[data model ^long mn ^long mx]
(let [interpolator (i/cubic-spline (map first data) (map second data))
mx5 (+ mx 5)
mn5 (- mn 5)]
(fn [a b c d e]
(let [f (model a b c d e)]
(reduce m/fast+ (map #(m/sq (- ^double (f %)
^double (interpolator %))) (range mn5 mx5 5)))))))
(o/scan-and-minimize :bobyqa (target green2 model1 6600 40000) {:bounds [[-10 10] [-10 10] [-10 10] [-3 3] [-3 3]]
:N 10000 :n 0.0001})
;; => [(0.4860175851734596 0.1802139719519286 -1.397716496795082 -0.00803698899233844 -0.14573069517701578) 4.363308910521639E-6]
(o/scan-and-minimize :bobyqa (target green1 model2 1000 6500) {:bounds [[-10 10] [-10 10] [-10 10] [-3 3] [-3 3]]
:N 100000 :n 0.0001})
;; => [(1.226916242502167 -1.3109482654223614 -5.089297600846147 0.6453936305542096 -0.44267061967913873) 0.0018388279703696142]
;; => [(1.2269162447743842 -1.310948623994376 -5.089297141345559 0.6453936329247667 -0.4426706118201436) 0.0018388279703696637]
;; => [(1.2220135516129107 0.18836704726583828 -0.45254967419913894 -0.20311048991230413 -1.7135062425202376) 0.004231835561962079]
;; => [(-3.0131582997113187 -4.922273819538732 3.091903745205893 -0.14721253826630887 0.6154140390408297) 0.003554974341401453]
;; => [(-12.386536553505412 -3.094557282591737 5.173139856074752 -0.17330930316780155 1.1564950471694004) 0.0037606068232236395]
;; => [(-5.511565134977287 -5.744574985934888 4.574181554940019 -0.19708641156263257 0.028222799015217615) 0.003987637473741095]
;; => [(1.4482135833497252 -40.700961964512004 -2.142179287263595 -0.2636809500303329 -2.7957342578778768) 0.004650663859634648]
;; => [(1.447903726979266 -8.9984137373161 -2.1439776890406956 -0.265517918810691 0.5991307238663346) 0.004562414289320711]
;; => [(1.6840838397819897 -99.71714926155681 -4.579238266745224 -0.32956031267716096 2.158216994282502) 0.005534876649237569]
;; => [(1.8121907947245866 -10.0 -3.064411215500388 -0.35676124548843896 1.4555010133060404) 0.00590127741044287]
;; => [(1.909233158822293 -5.0 -2.4684545984679 -0.37584834549400536 1.1791140924791639) 0.006168394011999948]
;; => [(2.069012399575755 -3.0 -1.8860429155647802 -0.4048863751262534 0.909063264425855) 0.0065851369612035205]
;; => [(2.0616560157470754 -3.0 -1.8975905160099678 -0.4144153095386858 0.9064519501571703) 0.007644837024937211]
(o/scan-and-minimize :powell (target red model1 6600 40000) {:bounds [[-3.0 3.0] [-3.0 3.0] [-3.0 3.0] [-3.0 3.0] [-3.0 3.0]]
:N 100000 :n 0.0001})
;; => [(0.32068362618584273 0.19668730877673762 -1.5139012907556737 -0.013883432789258415 -0.21298613432655075) 1.6767257396720742E-5]
;; => [(0.2798064642553463 0.21511885647544188 -1.2434889359808228 0.004630271441785413 -0.27979437859882605) 7.56331269776285E-4]
;; => [(0.34805608680781236 0.19268923376972438 -1.7811542116614576 -0.027793634548122677 -0.14607555831042743) 6.546624973909867E-4]
;; => [(0.3701445040872087 0.21274174690934944 -2.15665811181558 -0.039272792499047714 -0.04213589556840892) 0.002766315455069795]
;; => [(0.33521978223836524 0.193429911143376 -1.6462024292692703 -0.021030922926172042 -0.17986375758554604) 1.6660314104055508E-4]
;; => [(0.36015340169917776 0.19142596722910604 -1.9149582624085122 -0.03456166761348896 -0.1168765497390514) 0.0016652540054863853]
;; => [(0.37714377097478974 0.22654410250301954 -2.310445787637613 -0.04318259028762939) 0.003945831706188418]
;; => [(0.37720381978588435 0.22647764580716478 -2.3109138058217393 -0.0432233681039607) 0.003945787739820289]
;; => [(0.3771905345934732 0.2264925199768012 -2.3108045021722097 -0.04321429411826343) 0.003945783728163899]
(o/scan-and-minimize :bobyqa (target blue model2 2000 6500) {:bounds [[-10 10] [-25 25] [-10 10] [-3 3] [-3 3]]
:N 100000 :n 0.0001})
;; => [(1.677499032830161 -0.02313594016938082 -4.221279555918655 1.6550275798913296 -1.1367244820333684) 1.3479619724870819E-5]
;; => [(-1.4791289011636133 17.318721309486648 -1.9357661329610458 -0.485218141842477 0.2642034306673546) 5.75063665517416E-5]
;; => [(-4.63725475595295 10.0 -1.2570485130843558 -0.8554132050277921 0.8858120548777598) 3.8653164093778745E-4]
(defn kelvin-red
^double [^double k]
(if (< k 6500)
255.0
(let [kk (* 0.0001 k)]
(min 255.0 (* 255.0 (c/from-linear (+ 0.32068362618584273
(* 0.19668730877673762 (m/pow (+ -0.21298613432655075 kk) -1.5139012907556737))
(* -0.013883432789258415 (m/ln kk)))))))))
(defn- kelvin-green1
^double [^double k]
(let [kk (* 0.0001 k)
eekk (+ kk -0.44267061967913873)]
(max 0.0 (* 255.0 (c/from-linear (+ 1.226916242502167
(* -1.3109482654223614 eekk eekk eekk (m/exp (* eekk -5.089297600846147)))
(* 0.6453936305542096
(m/ln kk))))))))
(defn- kelvin-green2
^double [^double k]
(let [kk (* 0.0001 k)]
(* 255.0 (c/from-linear (+ 0.4860175851734596
(* 0.1802139719519286 (m/pow (+ -0.14573069517701578 kk) -1.397716496795082))
(* -0.00803698899233844 (m/ln kk)))))))
(defn kelvin-green
^double [^double k]
(cond
(< k 800) 0.0
(< k 6550)(kelvin-green1 k)
:else (kelvin-green2 k)))
(defn kelvin-blue
^double [^double k]
(cond
(< k 1900) 0.0
(> k 6600) 255.0
:else (let [kk (* 0.0001 k)
eekk (+ kk -1.1367244820333684)]
(m/constrain (* 255.0 (c/from-linear (+ 1.677499032830161
(* -0.02313594016938082 eekk eekk eekk
(m/exp (* eekk -4.221279555918655)))
(* 1.6550275798913296
(m/ln kk))))) 0.0 255.0))))
(defn check-errors
[f data]
(filter #(not (zero? ^long (second %))) (map (fn [[k ^long r]]
(let [kk (c/lclamp255 (f k))]
[k (- kk r)])) data)))
(check-errors kelvin-red rgb-red)
;; => ([7300 -1] [10300 1] [11000 1] [15800 -1])
(check-errors kelvin-green rgb-green)
;; => ([1000 2] [1100 1] [1300 -1] [1400 -1] [1500 -2] [1600 -1] [1800 1] [1900 1] [2000 1] [2100 1] [2200 1])
(check-errors kelvin-blue rgb-blue)
;; => ([2000 -1] [2200 1] [2300 1] [2600 1])
;; API
(defn temperature
"Color representing given black body temperature `t` in Kelvins.
Reference: CIE 1964 10 degree CMFs
Using improved interpolation functions."
[^double t]
(c/color (kelvin-red t)
(kelvin-green t)
(kelvin-blue t)))
(temperature 4000);; => #vec4 [255.0, 208.71958942264393, 163.43568066637067, 255.0]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment