2023年政策修订增补工作正在进行中,欢迎参与!
Module:Sandbox/Grandom/calc
跳转到导航
跳转到搜索
local module = {}
local getArgs = require('Module:Arguments').getArgs
local Color = require('Module:color')
function module.main(frame)
local args = getArgs(frame)
local colors = {}
local a = {args['LtMAG'] or 1 , args['ChrMAG'] or 3 , args['LtMAX'] or 225 , args['LtMIN'] or 0 , args['ChrMAX'] or 200}
local col_o = Color.create(args[1]):rgb().value
local l2 = math.min(math.max(a[1]*(0.2126*col_o[1]^2+0.7152*col_o[2]^2+0.0722*col_o[3]^2) , a[4]^2) , a[3]^2 , 65025)
local col_t = convert(l2, col_o, a[2], a[5])
colors['o'] = toString(col_o, args['alpha-o'] or 1)
colors['t'] = toString(col_t, args['alpha-t'] or 1)
frame:callParserFunction('#vardefine' , 'color-t' , colors['t'])
for k, v in pairs(args) do
if mw.ustring.sub(k, 1, 6) == 'color-' then
k = mw.ustring.sub(k, 7)
v = math.min(math.max(v, -100), 100)
local col_k = kCalc(col_t, l2, v)
colors[k] = toString(col_k, args['alpha-'..k] or 1)
frame:callParserFunction('#vardefine' , 'color-'..k , colors[k])
end
end
return colors[args['output'] or 't']
end
function convert(l2, rgb, m, c)
local h
local r, g, b = rgb[1], rgb[2], rgb[3]
if r > g then
if g > b then --rgb 0~60
h = (g - b)/(r - b)
return tCalc(h , 0.2126 , 0.7152 , 0.0722 , l2 , math.min(m*(r-b) , c*(-1286.9*h^4+1328.7*h^3-142.29*h^2+134.23*h+165.74)/200 , 255))
elseif b > r then --brg 240~300
h = (r - g)/(b - g)
rgb = tCalc(h , 0.0722 , 0.2126 , 0.7152 , l2 , math.min(m*(b-g) , c*(-53.74*h^2+37.053*h+129.88)/200 , 255))
return {rgb[2] , rgb[3] , rgb[1]}
else --rbg 300~360
h = (r - b)/(r - g)
rgb = tCalc(1-h , 0.2126 , 0.0722 , 0.7152 , l2 , math.min(m*(r-g) , c*(-49.395*h^2+101.94*h+113.19)/200 , 255))
return {rgb[1] , rgb[3] , rgb[2]}
end
else
if r > b then --grb 60~120
h = (g - r)/(g - b)
rgb = tCalc(1-h , 0.7152 , 0.2126 , 0.0722 , l2 , math.min(m*(g-b) , c*(29.76*h^2-104.35*h+199.48)/200 , 255))
return {rgb[2] , rgb[1] , rgb[3]}
elseif b > g then --bgr 180~240
h = (b - g)/(b - r)
rgb = tCalc(1-h , 0.0722 , 0.7152 , 0.2126 , l2 , math.min(m*(b-r) , c*(-1436.6*h^4+3559.6*h^3-2760.2*h^2+379.84*h+387.24)/200 , 255))
return {rgb[3] , rgb[2] , rgb[1]}
elseif g > r then --gbr 120~180
h = (b - r)/(g - r)
rgb = tCalc(h , 0.7152 , 0.0722 , 0.2126 , l2 , math.min(m*(g-r) , c*(-1404.8*h^4+2509.9*h^3-1063.4*h^2+220.65*h+124.89)/200 , 255))
return {rgb[3] , rgb[1] , rgb[2]}
else --r=g=b c=0
return tCalc(0 , 1 , 0 , 0 , l2 , 0)
end
end
end
function tCalc(h , k1 , k2 , k3 , l2 , c)
local c1 , c2 , c3
if l2 < (k1 + k2 * h ^ 2) * c ^ 2 then
c1 = (l2 / (k1 + k2 * h ^ 2)) ^ (1/2)
c2 = c1 * h
c3 = 0
elseif l2 > k1 * 65025 + k2 * (255 - c + h * c) ^ 2 + k3 * (255 - c) ^ 2 then
local A = k2 * (1 - h) ^ 2+ k3
c3 = ((A * l2 / 65025 - k1 * A - k2 * k3 * h ^ 2) ^ (1/2) - k2 * h * (1 - h)) * 255 / A
c2 = (255 - c3) * h + c3
c1 = 255
else
local B = k1 + k2 * h
c3 = ((B ^ 2 - k1 - k2 * h ^ 2) * c ^ 2 + l2) ^ (1/2) - B * c
c2 = c * h + c3
c1 = c + c3
end
return {c1 , c2 , c3}
end
function kCalc(rgb , l2 , t)
if t == 100 then
return { 255 , 255 , 255 }
elseif t < 0 then
return { rgb[1]*(1 + t / 100)^(1/2) , rgb[2]*(1 + t / 100)^(1/2) , rgb[3]*(1 + t / 100)^(1/2) }
else
local h1 = (255 - rgb[1])/(765 - rgb[1] - rgb[2] - rgb[3])
local h2 = (255 - rgb[2])/(765 - rgb[1] - rgb[2] - rgb[3])
local h3 = (255 - rgb[3])/(765 - rgb[1] - rgb[2] - rgb[3])
local A = 0.2126 * h1 ^ 2 + 0.7152 * h2 ^ 2 + 0.0722 * h3 ^ 2
local B = 0.2126 * h1 + 0.7152 * h2 + 0.0722 * h3
local X = (B - (B ^ 2 - A * (1 - l2 / 65025) * (1 - t / 100)) ^ (1/2)) * 255 / A
return { 255-h1*X , 255-h2*X , 255-h3*X }
end
end
function toString(rgb, alpha)
function toHex(num)
local int, float = math.modf(num)
if float > 0.4 then int = int + 1 end
local zero = ''
if int < 16 then zero = '0' end
return zero..string.format('%X', int)
end
local r, g, b = math.floor(rgb[1] + 0.5), math.floor(rgb[2] + 0.5), math.floor(rgb[3] + 0.5)
if alpha == 1 then
return toHex(r)..toHex(g)..toHex(b)
else
return 'rgba('..r..','..g..','..b..','..alpha..')'
end
end
return module