diff --git a/bundles/org.openhab.core/src/main/java/org/openhab/core/util/ColorUtil.java b/bundles/org.openhab.core/src/main/java/org/openhab/core/util/ColorUtil.java index 2e6be3d54ab..1f05311d7d4 100644 --- a/bundles/org.openhab.core/src/main/java/org/openhab/core/util/ColorUtil.java +++ b/bundles/org.openhab.core/src/main/java/org/openhab/core/util/ColorUtil.java @@ -650,4 +650,530 @@ public Point closest(Point p) { return retVal; } } + + /** + * Lookup table for converting colour temperatures in Kelvin to a point in the CIE XY colour space. + * Elements of the array comprise three parts: colour temperature (K), X coordinate, Y coordinate. + */ + private static final double[][] KELVIN_TO_XY_LOOKUP_TABLE = { + //@formatter:off + { 2000, 0.526676280311873, 0.41329727450763 }, + { 2010, 0.52558700949522, 0.413461772751086 }, + { 2020, 0.524501547047308, 0.413618464845305 }, + { 2030, 0.523419902728187, 0.413767442985273 }, + { 2040, 0.522342085989252, 0.413908799143933 }, + { 2050, 0.521268105968449, 0.414042625047528 }, + { 2060, 0.520197971485871, 0.414169012151805 }, + { 2070, 0.519131691039726, 0.414288051619026 }, + { 2080, 0.518069272802678, 0.414399834295808 }, + { 2090, 0.51701072461855, 0.41450445069175 }, + { 2100, 0.515956053999373, 0.414601990958848 }, + { 2110, 0.514905268122789, 0.414692544871688 }, + { 2120, 0.513858373829776, 0.414776201808388 }, + { 2130, 0.512815377622702, 0.414853050732289 }, + { 2140, 0.511776285663697, 0.414923180174373 }, + { 2150, 0.510741103773325, 0.414986678216401 }, + { 2160, 0.509709837429556, 0.415043632474748 }, + { 2170, 0.508682491767023, 0.415094130084932 }, + { 2180, 0.507659071576558, 0.415138257686807 }, + { 2190, 0.506639581304996, 0.415176101410431 }, + { 2200, 0.505624025055233, 0.415207746862562 }, + { 2210, 0.504612406586543, 0.415233279113804 }, + { 2220, 0.50360472931513, 0.415252782686356 }, + { 2230, 0.502600996314909, 0.415266341542373 }, + { 2240, 0.501601210318512, 0.41527403907292 }, + { 2250, 0.500605373718514, 0.415275958087495 }, + { 2260, 0.499613488568853, 0.415272180804119 }, + { 2270, 0.498625556586457, 0.415262788839981 }, + { 2280, 0.497641579153048, 0.415247863202608 }, + { 2290, 0.496661557317139, 0.415227484281571 }, + { 2300, 0.495685491796189, 0.415201731840687 }, + { 2310, 0.494713382978936, 0.415170685010734 }, + { 2320, 0.49374523092787, 0.415134422282633 }, + { 2330, 0.492781035381868, 0.415093021501115 }, + { 2340, 0.491820795758963, 0.415046559858839 }, + { 2350, 0.490864511159246, 0.414995113890958 }, + { 2360, 0.489912180367896, 0.414938759470118 }, + { 2370, 0.488963801858331, 0.414877571801882 }, + { 2380, 0.488019373795462, 0.414811625420557 }, + { 2390, 0.48707889403907, 0.41474099418543 }, + { 2400, 0.486142360147258, 0.414665751277374 }, + { 2410, 0.485209769380024, 0.414585969195845 }, + { 2420, 0.484281118702893, 0.41450171975623 }, + { 2430, 0.483356404790651, 0.414413074087558 }, + { 2440, 0.482435624031141, 0.41432010263054 }, + { 2450, 0.481518772529133, 0.414222875135951 }, + { 2460, 0.480605846110259, 0.414121460663327 }, + { 2470, 0.479696840325004, 0.414015927579967 }, + { 2480, 0.478791750452749, 0.413906343560247 }, + { 2490, 0.477890571505866, 0.413792775585208 }, + { 2500, 0.476993298233858, 0.413675289942435 }, + { 2510, 0.476099925127525, 0.413553952226202 }, + { 2520, 0.475210446423188, 0.413428827337877 }, + { 2530, 0.474324856106916, 0.413299979486579 }, + { 2540, 0.473443147918802, 0.413167472190078 }, + { 2550, 0.472565315357245, 0.413031368275923 }, + { 2560, 0.471691351683258, 0.412891729882807 }, + { 2570, 0.470821249924792, 0.412748618462133 }, + { 2580, 0.469955002881062, 0.412602094779799 }, + { 2590, 0.469092603126886, 0.412452218918178 }, + { 2600, 0.468234043017033, 0.41229905027829 }, + { 2610, 0.46737931469056, 0.412142647582159 }, + { 2620, 0.466528410075157, 0.411983068875347 }, + { 2630, 0.465681320891482, 0.411820371529656 }, + { 2640, 0.464838038657489, 0.411654612245991 }, + { 2650, 0.463998554692746, 0.411485847057383 }, + { 2660, 0.463162860122743, 0.411314131332149 }, + { 2670, 0.462330945883173, 0.411139519777208 }, + { 2680, 0.461502802724214, 0.41096206644152 }, + { 2690, 0.460678421214773, 0.410781824719658 }, + { 2700, 0.459857791746717, 0.410598847355503 }, + { 2710, 0.459040904539081, 0.410413186446054 }, + { 2720, 0.458227749642249, 0.410224893445347 }, + { 2730, 0.457418316942099, 0.410034019168485 }, + { 2740, 0.456612596164132, 0.409840613795755 }, + { 2750, 0.455810576877562, 0.409644726876854 }, + { 2760, 0.455012248499377, 0.409446407335191 }, + { 2770, 0.45421760029836, 0.40924570347228 }, + { 2780, 0.453426621399085, 0.409042662972206 }, + { 2790, 0.452639300785869, 0.408837332906172 }, + { 2800, 0.451855627306685, 0.408629759737106 }, + { 2810, 0.451075589677048, 0.408419989324343 }, + { 2820, 0.450299176483844, 0.408208066928357 }, + { 2830, 0.449526376189136, 0.407994037215556 }, + { 2840, 0.448757177133914, 0.407777944263126 }, + { 2850, 0.447991567541816, 0.407559831563923 }, + { 2860, 0.447229535522791, 0.407339742031414 }, + { 2870, 0.446471069076735, 0.407117718004646 }, + { 2880, 0.445716156097067, 0.406893801253269 }, + { 2890, 0.444964784374273, 0.406668032982576 }, + { 2900, 0.444216941599399, 0.406440453838584 }, + { 2910, 0.443472615367494, 0.406211103913138 }, + { 2920, 0.442731793181017, 0.405980022749035 }, + { 2930, 0.441994462453189, 0.405747249345174 }, + { 2940, 0.441260610511305, 0.405512822161723 }, + { 2950, 0.440530224599989, 0.405276779125295 }, + { 2960, 0.439803291884415, 0.405039157634144 }, + { 2970, 0.439079799453468, 0.404799994563365 }, + { 2980, 0.438359734322871, 0.404559326270101 }, + { 2990, 0.437643083438248, 0.404317188598758 }, + { 3000, 0.436929833678155, 0.404073616886221 }, + { 3010, 0.436219971857052, 0.403828645967064 }, + { 3020, 0.435513484728235, 0.403582310178768 }, + { 3030, 0.434810358986718, 0.403334643366923 }, + { 3040, 0.434110581272061, 0.403085678890438 }, + { 3050, 0.433414138171168, 0.402835449626724 }, + { 3060, 0.432721016221012, 0.402583987976887 }, + { 3070, 0.43203120191134, 0.402331325870893 }, + { 3080, 0.431344681687312, 0.402077494772728 }, + { 3090, 0.4306614419521, 0.401822525685539 }, + { 3100, 0.429981469069442, 0.401566449156763 }, + { 3110, 0.429304749366147, 0.401309295283229 }, + { 3120, 0.428631269134558, 0.401051093716253 }, + { 3130, 0.427961014634963, 0.400791873666696 }, + { 3140, 0.427293972097967, 0.400531663910017 }, + { 3150, 0.426630127726814, 0.400270492791288 }, + { 3160, 0.425969467699671, 0.400008388230194 }, + { 3170, 0.425311978171859, 0.399745377726 }, + { 3180, 0.424657645278049, 0.399481488362498 }, + { 3190, 0.424006455134406, 0.399216746812922 }, + { 3200, 0.423358393840696, 0.398951179344833 }, + { 3210, 0.422713447482352, 0.39868481182498 }, + { 3220, 0.422071602132489, 0.398417669724122 }, + { 3230, 0.421432843853882, 0.39814977812183 }, + { 3240, 0.420797158700909, 0.397881161711245 }, + { 3250, 0.42016453272144, 0.39761184480381 }, + { 3260, 0.419534951958697, 0.397341851333969 }, + { 3270, 0.418908402453069, 0.397071204863828 }, + { 3280, 0.418284870243884, 0.396799928587787 }, + { 3290, 0.41766434137115, 0.396528045337128 }, + { 3300, 0.417046801877253, 0.396255577584578 }, + { 3310, 0.416432237808611, 0.395982547448827 }, + { 3320, 0.415820635217303, 0.395708976699012 }, + { 3330, 0.415211980162654, 0.395434886759171 }, + { 3340, 0.414606258712775, 0.395160298712644 }, + { 3350, 0.414003456946084, 0.394885233306455 }, + { 3360, 0.41340356095278, 0.394609710955639 }, + { 3370, 0.41280655683628, 0.394333751747546 }, + { 3380, 0.412212430714629, 0.39405737544609 }, + { 3390, 0.411621168721873, 0.393780601495975 }, + { 3400, 0.411032757009395, 0.393503449026874 }, + { 3410, 0.410447181747219, 0.393225936857565 }, + { 3420, 0.409864429125286, 0.392948083500039 }, + { 3430, 0.409284485354692, 0.392669907163558 }, + { 3440, 0.408707336668894, 0.39239142575868 }, + { 3450, 0.408132969324891, 0.39211265690124 }, + { 3460, 0.407561369604368, 0.391833617916295 }, + { 3470, 0.406992523814813, 0.391554325842027 }, + { 3480, 0.406426418290599, 0.391274797433607 }, + { 3490, 0.405863039394048, 0.390995049167019 }, + { 3500, 0.405302373516452, 0.390715097242847 }, + { 3510, 0.404744407079075, 0.390434957590016 }, + { 3520, 0.404189126534126, 0.390154645869498 }, + { 3530, 0.403636518365702, 0.389874177477982 }, + { 3540, 0.403086569090702, 0.389593567551495 }, + { 3550, 0.402539265259722, 0.389312830968992 }, + { 3560, 0.401994593457919, 0.389031982355903 }, + { 3570, 0.401452540305847, 0.388751036087639 }, + { 3580, 0.400913092460274, 0.388470006293066 }, + { 3590, 0.400376236614968, 0.388188906857933 }, + { 3600, 0.399841959501467, 0.387907751428262 }, + { 3610, 0.399310247889814, 0.387626553413704 }, + { 3620, 0.398781088589278, 0.387345325990855 }, + { 3630, 0.398254468449049, 0.387064082106531 }, + { 3640, 0.397730374358909, 0.386782834481003 }, + { 3650, 0.397208793249882, 0.386501595611205 }, + { 3660, 0.396689712094866, 0.386220377773894 }, + { 3670, 0.396173117909235, 0.385939193028774 }, + { 3680, 0.395658997751428, 0.385658053221589 }, + { 3690, 0.395147338723516, 0.385376969987172 }, + { 3700, 0.394638127971748, 0.38509595475246 }, + { 3710, 0.394131352687072, 0.384815018739475 }, + { 3720, 0.393627000105649, 0.384534172968266 }, + { 3730, 0.393125057509339, 0.384253428259816 }, + { 3740, 0.392625512226168, 0.383972795238911 }, + { 3750, 0.392128351630781, 0.383692284336979 }, + { 3760, 0.391633563144876, 0.383411905794889 }, + { 3770, 0.391141134237623, 0.383131669665717 }, + { 3780, 0.390651052426057, 0.382851585817475 }, + { 3790, 0.390163305275465, 0.382571663935814 }, + { 3800, 0.389677880399752, 0.382291913526683 }, + { 3810, 0.389194765461792, 0.382012343918955 }, + { 3820, 0.388713948173757, 0.38173296426703 }, + { 3830, 0.388235416297444, 0.381453783553394 }, + { 3840, 0.387759157644574, 0.38117481059115 }, + { 3850, 0.387285160077084, 0.380896054026513 }, + { 3860, 0.386813411507402, 0.380617522341278 }, + { 3870, 0.386343899898705, 0.380339223855255 }, + { 3880, 0.385876613265173, 0.380061166728665 }, + { 3890, 0.385411539672215, 0.379783358964516 }, + { 3900, 0.384948667236696, 0.37950580841094 }, + { 3910, 0.384487984127144, 0.3792285227635 }, + { 3920, 0.384029478563943, 0.378951509567474 }, + { 3930, 0.383573138819519, 0.378674776220096 }, + { 3940, 0.383118953218507, 0.37839832997278 }, + { 3950, 0.382666910137919, 0.378122177933306 }, + { 3960, 0.382216998007281, 0.377846327067982 }, + { 3970, 0.38176920530878, 0.377570784203772 }, + { 3980, 0.381323520577382, 0.377295556030402 }, + { 3990, 0.380879932400953, 0.377020649102431 }, + { 4000, 0.380438429420364, 0.376746069841299 }, + { 4010, 0.379999000329579, 0.376471824537343 }, + { 4020, 0.379561633875749, 0.376197919351794 }, + { 4030, 0.37912631885928, 0.375924360318735 }, + { 4040, 0.378693044133903, 0.37565115334704 }, + { 4050, 0.378261798606731, 0.375378304222286 }, + { 4060, 0.377832571238301, 0.37510581860864 }, + { 4070, 0.377405351042622, 0.374833702050712 }, + { 4080, 0.376980127087195, 0.374561959975396 }, + { 4090, 0.376556888493043, 0.37429059769367 }, + { 4100, 0.376135624434723, 0.374019620402386 }, + { 4110, 0.37571632414033, 0.373749033186026 }, + { 4120, 0.375298976891495, 0.373478841018437 }, + { 4130, 0.37488357202338, 0.373209048764539 }, + { 4140, 0.374470098924658, 0.372939661182012 }, + { 4150, 0.374058547037489, 0.372670682922962 }, + { 4160, 0.373648905857491, 0.372402118535558 }, + { 4170, 0.373241164933703, 0.372133972465647 }, + { 4180, 0.372835313868541, 0.371866249058352 }, + { 4190, 0.372431342317747, 0.371598952559641 }, + { 4200, 0.372029239990332, 0.371332087117875 }, + { 4210, 0.371628996648516, 0.371065656785341 }, + { 4220, 0.371230602107658, 0.370799665519753 }, + { 4230, 0.37083404623618, 0.370534117185738 }, + { 4240, 0.370439318955492, 0.370269015556301 }, + { 4250, 0.370046410239904, 0.370004364314267 }, + { 4260, 0.369655310116535, 0.369740167053704 }, + { 4270, 0.369266008665223, 0.369476427281325 }, + { 4280, 0.368878496018416, 0.369213148417869 }, + { 4290, 0.368492762361075, 0.368950333799466 }, + { 4300, 0.368108797930561, 0.368687986678976 }, + { 4310, 0.36772659301652, 0.36842611022732 }, + { 4320, 0.367346137960767, 0.368164707534776 }, + { 4330, 0.36696742315716, 0.36790378161227 }, + { 4340, 0.366590439051477, 0.367643335392644 }, + { 4350, 0.366215176141282, 0.367383371731904 }, + { 4360, 0.36584162497579, 0.36712389341045 }, + { 4370, 0.365469776155733, 0.366864903134292 }, + { 4380, 0.365099620333213, 0.366606403536243 }, + { 4390, 0.364731148211558, 0.366348397177103 }, + { 4400, 0.364364350545175, 0.366090886546814 }, + { 4410, 0.363999218139393, 0.365833874065608 }, + { 4420, 0.363635741850315, 0.365577362085137 }, + { 4430, 0.363273912584652, 0.365321352889581 }, + { 4440, 0.362913721299567, 0.365065848696745 }, + { 4450, 0.362555159002508, 0.36481085165914 }, + { 4460, 0.362198216751042, 0.364556363865043 }, + { 4470, 0.361842885652686, 0.36430238733955 }, + { 4480, 0.361489156864733, 0.364048924045607 }, + { 4490, 0.36113702159408, 0.363795975885023 }, + { 4500, 0.360786471097048, 0.363543544699483 }, + { 4510, 0.360437496679207, 0.363291632271526 }, + { 4520, 0.36009008969519, 0.363040240325526 }, + { 4530, 0.359744241548512, 0.362789370528647 }, + { 4540, 0.359399943691386, 0.362539024491787 }, + { 4550, 0.35905718762453, 0.362289203770517 }, + { 4560, 0.358715964896985, 0.36203990986599 }, + { 4570, 0.35837626710592, 0.361791144225849 }, + { 4580, 0.358038085896437, 0.361542908245116 }, + { 4590, 0.357701412961382, 0.361295203267073 }, + { 4600, 0.357366240041146, 0.361048030584121 }, + { 4610, 0.357032558923467, 0.360801391438638 }, + { 4620, 0.356700361443233, 0.360555287023811 }, + { 4630, 0.356369639482281, 0.360309718484469 }, + { 4640, 0.356040384969197, 0.360064686917893 }, + { 4650, 0.355712589879109, 0.359820193374621 }, + { 4660, 0.35538624623349, 0.359576238859237 }, + { 4670, 0.355061346099949, 0.359332824331149 }, + { 4680, 0.354737881592023, 0.359089950705356 }, + { 4690, 0.354415844868975, 0.358847618853204 }, + { 4700, 0.354095228135586, 0.358605829603133 }, + { 4710, 0.353776023641942, 0.358364583741404 }, + { 4720, 0.353458223683228, 0.358123882012824 }, + { 4730, 0.353141820599519, 0.357883725121459 }, + { 4740, 0.352826806775565, 0.357644113731333 }, + { 4750, 0.352513174640586, 0.357405048467119 }, + { 4760, 0.35220091666805, 0.357166529914816 }, + { 4770, 0.351890025375474, 0.356928558622422 }, + { 4780, 0.351580493324198, 0.356691135100592 }, + { 4790, 0.351272313119179, 0.356454259823288 }, + { 4800, 0.350965477408777, 0.356217933228418 }, + { 4810, 0.350659978884535, 0.355982155718466 }, + { 4820, 0.350355810280973, 0.355746927661114 }, + { 4830, 0.350052964375366, 0.355512249389855 }, + { 4840, 0.349751433987532, 0.355278121204588 }, + { 4850, 0.349451211979616, 0.355044543372218 }, + { 4860, 0.349152291255876, 0.35481151612724 }, + { 4870, 0.348854664762465, 0.354579039672309 }, + { 4880, 0.348558325487217, 0.35434711417881 }, + { 4890, 0.348263266459433, 0.354115739787415 }, + { 4900, 0.347969480749661, 0.353884916608634 }, + { 4910, 0.347676961469483, 0.353654644723354 }, + { 4920, 0.3473857017713, 0.353424924183371 }, + { 4930, 0.347095694848114, 0.353195755011921 }, + { 4940, 0.346806933933317, 0.352967137204187 }, + { 4950, 0.346519412300469, 0.352739070727817 }, + { 4960, 0.346233123263089, 0.352511555523418 }, + { 4970, 0.345948060174438, 0.352284591505058 }, + { 4980, 0.345664216427301, 0.352058178560741 }, + { 4990, 0.345381585453779, 0.351832316552895 }, + { 5000, 0.345100160725069, 0.35160700531884 }, + { 5010, 0.344819935751253, 0.35138224467125 }, + { 5020, 0.344540904081086, 0.351158034398612 }, + { 5030, 0.344263059301778, 0.350934374265679 }, + { 5040, 0.343986395038783, 0.350711264013907 }, + { 5050, 0.343710904955591, 0.350488703361895 }, + { 5060, 0.34343658275351, 0.350266692005812 }, + { 5070, 0.343163422171456, 0.350045229619827 }, + { 5080, 0.342891416985746, 0.349824315856515 }, + { 5090, 0.34262056100988, 0.349603950347275 }, + { 5100, 0.342350848094336, 0.349384132702732 }, + { 5110, 0.342082272126361, 0.349164862513132 }, + { 5120, 0.341814827029758, 0.348946139348737 }, + { 5130, 0.34154850676468, 0.348727962760208 }, + { 5140, 0.341283305327422, 0.348510332278986 }, + { 5150, 0.341019216750211, 0.348293247417664 }, + { 5160, 0.340756235101003, 0.348076707670355 }, + { 5170, 0.340494354483275, 0.347860712513058 }, + { 5180, 0.340233569035817, 0.347645261404009 }, + { 5190, 0.339973872932533, 0.347430353784033 }, + { 5200, 0.339715260382228, 0.347215989076895 }, + { 5210, 0.339457725628414, 0.347002166689633 }, + { 5220, 0.339201262949099, 0.346788886012898 }, + { 5230, 0.33894586665659, 0.346576146421281 }, + { 5240, 0.338691531097289, 0.346363947273638 }, + { 5250, 0.338438250651491, 0.346152287913411 }, + { 5260, 0.338186019733187, 0.345941167668941 }, + { 5270, 0.337934832789862, 0.34573058585378 }, + { 5280, 0.337684684302299, 0.345520541766991 }, + { 5290, 0.337435568784377, 0.345311034693453 }, + { 5300, 0.337187480782876, 0.345102063904155 }, + { 5310, 0.336940414877284, 0.344893628656486 }, + { 5320, 0.336694365679595, 0.344685728194521 }, + { 5330, 0.336449327834117, 0.344478361749302 }, + { 5340, 0.336205296017281, 0.34427152853912 }, + { 5350, 0.335962264937442, 0.344065227769781 }, + { 5360, 0.335720229334691, 0.34385945863488 }, + { 5370, 0.335479183980662, 0.343654220316063 }, + { 5380, 0.335239123678341, 0.343449511983289 }, + { 5390, 0.335000043261875, 0.343245332795082 }, + { 5400, 0.334761937596386, 0.343041681898789 }, + { 5410, 0.334524801577778, 0.342838558430825 }, + { 5420, 0.334288630132555, 0.342635961516917 }, + { 5430, 0.33405341821763, 0.342433890272344 }, + { 5440, 0.33381916082014, 0.342232343802175 }, + { 5450, 0.333585852957265, 0.342031321201502 }, + { 5460, 0.333353489676037, 0.341830821555668 }, + { 5470, 0.333122066053165, 0.341630843940493 }, + { 5480, 0.332891577194843, 0.341431387422495 }, + { 5490, 0.33266201823658, 0.341232451059109 }, + { 5500, 0.332433384343009, 0.341034033898904 }, + { 5510, 0.332205670707715, 0.34083613498179 }, + { 5520, 0.331978872553048, 0.34063875333923 }, + { 5530, 0.331752985129957, 0.340441887994442 }, + { 5540, 0.3315280037178, 0.340245537962605 }, + { 5550, 0.331303923624177, 0.340049702251049 }, + { 5560, 0.331080740184751, 0.339854379859459 }, + { 5570, 0.330858448763073, 0.339659569780063 }, + { 5580, 0.330637044750413, 0.339465270997818 }, + { 5590, 0.330416523565582, 0.339271482490602 }, + { 5600, 0.330196880654761, 0.339078203229392 }, + { 5610, 0.329978111491335, 0.338885432178446 }, + { 5620, 0.329760211575718, 0.338693168295479 }, + { 5630, 0.329543176435188, 0.338501410531837 }, + { 5640, 0.329327001623714, 0.338310157832671 }, + { 5650, 0.329111682721794, 0.338119409137101 }, + { 5660, 0.328897215336285, 0.337929163378386 }, + { 5670, 0.32868359510024, 0.337739419484084 }, + { 5680, 0.328470817672741, 0.337550176376214 }, + { 5690, 0.328258878738739, 0.337361432971415 }, + { 5700, 0.328047774008889, 0.337173188181098 }, + { 5710, 0.327837499219387, 0.3369854409116 }, + { 5720, 0.32762805013181, 0.336798190064338 }, + { 5730, 0.32741942253296, 0.33661143453595 }, + { 5740, 0.327211612234699, 0.336425173218445 }, + { 5750, 0.327004615073793, 0.336239404999346 }, + { 5760, 0.326798426911756, 0.336054128761828 }, + { 5770, 0.326593043634692, 0.335869343384858 }, + { 5780, 0.326388461153141, 0.33568504774333 }, + { 5790, 0.326184675401921, 0.3355012407082 }, + { 5800, 0.325981682339978, 0.335317921146619 }, + { 5810, 0.325779477950234, 0.335135087922056 }, + { 5820, 0.325578058239428, 0.334952739894432 }, + { 5830, 0.325377419237973, 0.334770875920243 }, + { 5840, 0.325177556999802, 0.334589494852681 }, + { 5850, 0.324978467602219, 0.334408595541759 }, + { 5860, 0.324780147145748, 0.334228176834424 }, + { 5870, 0.324582591753991, 0.33404823757468 }, + { 5880, 0.324385797573479, 0.333868776603699 }, + { 5890, 0.324189760773522, 0.333689792759937 }, + { 5900, 0.323994477546069, 0.333511284879243 }, + { 5910, 0.323799944105563, 0.333333251794967 }, + { 5920, 0.323606156688797, 0.33315569233807 }, + { 5930, 0.32341311155477, 0.332978605337232 }, + { 5940, 0.323220804984549, 0.332801989618949 }, + { 5950, 0.323029233281125, 0.33262584400764 }, + { 5960, 0.322838392769274, 0.332450167325745 }, + { 5970, 0.322648279795422, 0.332274958393826 }, + { 5980, 0.322458890727498, 0.332100216030663 }, + { 5990, 0.322270221954808, 0.331925939053347 }, + { 6000, 0.322082269887888, 0.331752126277376 }, + { 6010, 0.321895030958374, 0.331578776516748 }, + { 6020, 0.321708501618868, 0.331405888584047 }, + { 6030, 0.321522678342801, 0.331233461290538 }, + { 6040, 0.3213375576243, 0.331061493446248 }, + { 6050, 0.32115313597806, 0.330889983860056 }, + { 6060, 0.320969409939206, 0.330718931339777 }, + { 6070, 0.320786376063166, 0.330548334692243 }, + { 6080, 0.320604030925542, 0.330378192723386 }, + { 6090, 0.32042237112198, 0.330208504238316 }, + { 6100, 0.32024139326804, 0.330039268041404 }, + { 6110, 0.320061093999071, 0.329870482936352 }, + { 6120, 0.319881469970083, 0.329702147726276 }, + { 6130, 0.319702517855622, 0.329534261213777 }, + { 6140, 0.319524234349642, 0.329366822201013 }, + { 6150, 0.319346616165388, 0.329199829489774 }, + { 6160, 0.319169660035263, 0.32903328188155 }, + { 6170, 0.318993362710712, 0.328867178177603 }, + { 6180, 0.3188177209621, 0.328701517179031 }, + { 6190, 0.318642731578585, 0.32853629768684 }, + { 6200, 0.318468391368004, 0.328371518502004 }, + { 6210, 0.318294697156752, 0.328207178425535 }, + { 6220, 0.31812164578966, 0.328043276258542 }, + { 6230, 0.31794923412988, 0.327879810802294 }, + { 6240, 0.317777459058767, 0.327716780858286 }, + { 6250, 0.317606317475763, 0.32755418522829 }, + { 6260, 0.317435806298278, 0.32739202271442 }, + { 6270, 0.317265922461579, 0.327230292119189 }, + { 6280, 0.317096662918675, 0.327068992245565 }, + { 6290, 0.316928024640201, 0.326908121897025 }, + { 6300, 0.316760004614306, 0.326747679877612 }, + { 6310, 0.316592599846543, 0.326587664991987 }, + { 6320, 0.316425807359756, 0.326428076045483 }, + { 6330, 0.316259624193968, 0.326268911844154 }, + { 6340, 0.316094047406274, 0.326110171194829 }, + { 6350, 0.315929074070729, 0.325951852905159 }, + { 6360, 0.315764701278241, 0.325793955783666 }, + { 6370, 0.315600926136464, 0.325636478639792 }, + { 6380, 0.315437745769688, 0.325479420283945 }, + { 6390, 0.315275157318735, 0.325322779527545 }, + { 6400, 0.315113157940854, 0.325166555183068 }, + { 6410, 0.314951744809611, 0.325010746064094 }, + { 6420, 0.314790915114793, 0.324855350985344 }, + { 6430, 0.314630666062295, 0.324700368762729 }, + { 6440, 0.314470994874025, 0.324545798213387 }, + { 6450, 0.314311898787797, 0.324391638155726 }, + { 6460, 0.314153375057231, 0.324237887409465 }, + { 6470, 0.31399542095165, 0.324084544795669 }, + { 6480, 0.313838033755984, 0.323931609136792 }, + { 6490, 0.313681210770667, 0.323779079256713 }, + { 6500, 0.313524949311538, 0.323626953980771 }, + { 6510, 0.313369246709745, 0.323475232135805 }, + { 6520, 0.313214100311644, 0.323323912550187 }, + { 6530, 0.313059507478705, 0.323172994053855 }, + { 6540, 0.312905465587415, 0.323022475478352 }, + //@formatter:on + }; + + /** + * Search the 'KELVIN_TO_XY_LOOKUP_TABLE' for the XY entry closest to the given colour temperature. + * Uses a recursive 'QuickSearch' algorithm. + * + * @param kelvin the colour temperature in K to find + * @param min the first index in the lookup table + * @param max the last index in the lookup table + * @return an array with the found CIE colour XY values + * @throws IndexOutOfBoundsException if the colour temperature is out of range 'min' .. 'max' + */ + private static double[] kelvinToXY(double kelvin, int min, int max) throws IndexOutOfBoundsException { + if (min < 0 || max < min || max >= KELVIN_TO_XY_LOOKUP_TABLE.length) { + throw new IndexOutOfBoundsException("kelvinToXY() 'min' or 'max' index out of bounds"); + } + int mid = (min + max) / 2; + double delta = kelvin - KELVIN_TO_XY_LOOKUP_TABLE[mid][0]; + if (delta >= 10) { + return kelvinToXY(kelvin, mid + 1, max); + } + if (delta <= -10) { + return kelvinToXY(kelvin, min, mid - 1); + } + return new double[] { KELVIN_TO_XY_LOOKUP_TABLE[mid][1], KELVIN_TO_XY_LOOKUP_TABLE[mid][2] }; + } + + /** + * Convert a colour temperature in Kelvin to a point in the CIE XY colour space. + * Uses a lookup table as described here. + * + * @param kelvin the colour temperature in K to be converted + * @return an array with the found CIE colour XY values + * @throws IndexOutOfBoundsException if the colour temperature is out of range 2000K .. 6500K + */ + public static double[] kelvinToXY(double kelvin) throws IndexOutOfBoundsException { + int indexMax = KELVIN_TO_XY_LOOKUP_TABLE.length - 1; + double kelvinMin = KELVIN_TO_XY_LOOKUP_TABLE[0][0]; + double kelvinMax = KELVIN_TO_XY_LOOKUP_TABLE[indexMax][0]; + if (kelvin < kelvinMin || kelvin > kelvinMax) { + throw new IndexOutOfBoundsException( + String.format("kelvinToXY() %.0f K out of range %.0f K .. %.0f K", kelvin, kelvinMin, kelvinMax)); + } + return kelvinToXY(kelvin, 0, indexMax); + } + + /** + * Convert a point in the CIE XY colour space to a colour temperature in Kelvin. + * Uses McCamy's approximation as described here. + * + * @param xy an array with the CIE colour XY values to be converted + * @return the colour temperature in K + * @throws IndexOutOfBoundsException if the wrong number of arguments is provided + */ + public static double xyToKelvin(double[] xy) { + if (xy.length != 2) { + throw new IllegalArgumentException("xyToKelvin() requires 2 arguments"); + } + double n = (xy[0] - 0.3320) / (0.1858 - xy[1]); + return (437 * Math.pow(n, 3)) + (3601 * Math.pow(n, 2)) + (6861 * n) + 5517; + } } diff --git a/bundles/org.openhab.core/src/test/java/org/openhab/core/util/ColorUtilTest.java b/bundles/org.openhab.core/src/test/java/org/openhab/core/util/ColorUtilTest.java index 62e06e25cfa..881dca54e74 100644 --- a/bundles/org.openhab.core/src/test/java/org/openhab/core/util/ColorUtilTest.java +++ b/bundles/org.openhab.core/src/test/java/org/openhab/core/util/ColorUtilTest.java @@ -16,6 +16,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.lessThan; import static org.hamcrest.Matchers.lessThanOrEqualTo; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -641,4 +642,22 @@ public void rgbwToHsb2hsbToRgbw(double[] rgbw) { rgbw2[3].doubleValue() / 100, e.getMessage())); } } + + /** + * Test conversion between colour temperature in Kelvin and points on the colour + * temperature locus in the CIE XY colour space + */ + @Test + void testKelvinXyConversion() { + // test minimum and maximum limits 500..153 Mirek i.e. 2000..6536 Kelvin + assertThrows(IndexOutOfBoundsException.class, () -> ColorUtil.kelvinToXY(1000000 / 501)); + assertDoesNotThrow(() -> ColorUtil.kelvinToXY(1000000 / 500)); + assertDoesNotThrow(() -> ColorUtil.kelvinToXY(1000000 / 153)); + assertThrows(IndexOutOfBoundsException.class, () -> ColorUtil.kelvinToXY(1000000 / 152)); + + // test round trips K => XY => K + for (double kelvin = 2000; kelvin <= 6536; kelvin += 5) { + assertEquals(kelvin, ColorUtil.xyToKelvin(ColorUtil.kelvinToXY(kelvin)), 15); + } + } }