JavaScript(ES6),98 95 94字节
注意到ħ在[0360)和小号 / 大号在[0,1) 。输出R,G和B为[0,1)中3个浮点的数组。
(H,S,L)=>[5,3,1].map(i=>A(L*2)*S*([1,Y,0,0,Y,1][(i-~H)%6]-.5)+L,Y=(A=n=>n>1?2-n:n)((H/=60)%2))
测试用例
此摘要将结果转换回[0,255]。
let f =
(H,S,L)=>[5,3,1].map(i=>A(L*2)*S*([1,Y,0,0,Y,1][(i-~H)%6]-.5)+L,Y=(A=n=>n>1?2-n:n)((H/=60)%2))
format = a => JSON.stringify(a.map(v => v * 255 + 0.5 | 0))
console.log(format(f( 0, 0.00, 0.00))) // 0 0 0
console.log(format(f( 90, 0.56, 0.17))) // 43 68 19
console.log(format(f(202, 0.19, 0.39))) // 81 104 118
console.log(format(f( 72, 0.55, 0.26))) // 88 103 30
怎么样?
初始化代码
Y = ( // we compute Y = 1 - |(H/60) mod 2 - 1| = X / C
A = n => // A = function that returns 1 - |n - 1|
n > 1 ? // first compare n with 1
2 - n // which allows to simplify the formula to either 2 - n
: // or
n // just n
)((H /= 60) % 2) // divide H by 60 and compute Y = A(H % 2)
主要代号
[5, 3, 1].map(i => // for each i in (5, 3, 1):
A(L * 2) * S * ( // compute (1 - |2L - 1|) * S (this is C), and multiply it by:
[1, Y, 0, 0, Y, 1] // either 0, 1 or Y (let's call this factor K), picked from
[(i - ~H) % 6] // a cyclic sequence of period 6, using i and ~H (-6 ≤ ~H ≤ -1)
- .5 // minus 1/2
) // this gives: C(K - 1/2) = CK - C/2, where CK = 0, C or X
+ L // we add L, leading to CK - C/2 + L = CK + m
) // end of map() --> returns [R, G, B]
(0,C,X)的排列
稍微棘手的部分是根据色相分量的角度生成(0,C,X)的正确排列。如下图所示,每个列值都是从周期6的相同循环序列中选取的,起始于不同的偏移量。在上面的代码中,我们使用-〜H而不是+ H,因为我们需要将H强制为整数。因此,偏移量是(5,3,1)而不是(0,4,2)。
C,X,0,0,X,C,C,X,0,0,X,C, ...
+------> C,X,0,0,X,C <---------> offset = 0, (0 - 1) mod 6 = 5
| +----> X,C,C,X,0,0 <---------> offset = 4, (4 - 1) mod 6 = 3
| | +--> 0,0,X,C,C,X <---------> offset = 2, (2 - 1) mod 6 = 1
| | |
(C,X,0) for 0 ≤ H < 60
(X,C,0) for 60 ≤ H < 120
(0,C,X) for 120 ≤ H < 180
(0,X,C) for 180 ≤ H < 240
(X,0,C) for 240 ≤ H < 300
(C,0,X) for 300 ≤ H < 360
H
的0-360
是[0,360)
,它会更好写成0-359
?