Module:Sandbox/AlexNB/nmColor: Difference between revisions

Content deleted Content added
AlexNB (talk | contribs)
No edit summary
AlexNB (talk | contribs)
No edit summary
 
(81 intermediate revisions by the same user not shown)
Line 28:
greenvalue = (645 - wavelength) / 65
bluevalue = 0
elseif (wavelength >= 645) and (wavelength <= 780) then
redvalue = 1
greenvalue = 0
Line 55:
local result='#' .. string.format("%.2X%.2X%.2X", 255*redvalue, 255*greenvalue, 255*bluevalue)
return result
end
 
local function absorption_to_visible(wavelength_abs)
-- code based on a color wheel drawn at: http://www2.chemistry.msu.edu/faculty/reusch/virttxtjml/spectrpy/uv-vis/spectrum.htm
local wavelength_vis
local minVioletIndigo = 380 -- originally, it was 400
local maxVioletIndigo = 430
local widthVioletIndigo = maxVioletIndigo - minVioletIndigo
local redsumminBlue = 0430
local bluesummaxBlue = 0490
local widthBlue = maxBlue - minBlue
local greensumminGreen = 0490
local numofitemsmaxGreen = 400560
local widthGreen = maxGreen - minGreen
local minYellow = 560
local maxYellow = 580
local widthYellow = maxYellow - minYellow
local minOrange = 580
local maxOrange = 650 -- originally, it was 620
local widthOrange = maxOrange - minOrange
local minRed = 650 -- originally, it was 620
local maxRed = 780 -- originally, it was 800
local widthRed = maxRed - minRed
if (wavelength_abs>=minVioletIndigo) and (wavelength_abs<=maxVioletIndigo) then
wavelength_vis = (wavelength_abs - minVioletIndigo)*widthYellow/widthVioletIndigo + minYellow
elseif (wavelength_abs>minBlue) and (wavelength_abs<=maxBlue) then
wavelength_vis = (wavelength_abs - minBlue)*widthOrange/widthBlue + minOrange
elseif (wavelength_abs>minGreen) and (wavelength_abs<=maxGreen) then
wavelength_vis = (wavelength_abs - minGreen)*widthRed/widthGreen + minRed
elseif (wavelength_abs>minYellow) and (wavelength_abs<=maxYellow) then
wavelength_vis = (wavelength_abs - minYellow)*widthVioletIndigo/widthYellow + minVioletIndigo
elseif (wavelength_abs>minOrange) and (wavelength_abs<=maxOrange) then
wavelength_vis = (wavelength_abs - minOrange)*widthBlue/widthOrange + minBlue
elseif (wavelength_abs>minRed) and (wavelength_abs<=maxRed) then
wavelength_vis = (wavelength_abs - minRed)*widthGreen/(widthRed + 20) + minGreen
-- one of the "corrected" versions: wavelength_vis = (wavelength_abs - minRed - 30)*widthGreen/widthRed + minGreen
end
return wavelength_vis
end
 
local minAntiMagenta = 550
local maxAntiMagenta = 570
 
local function process_magenta(wavelength_abs)
local redvalue_RED
local bluevalue_RED
local greenvalue_RED
local redvalue_BLUE
local bluevalue_BLUE
local greenvalue_BLUE
local widthAntiMagenta = maxAntiMagenta - minAntiMagenta
local bias_BLUE = (wavelength_abs - minAntiMagenta)/widthAntiMagenta
local bias_RED = (maxAntiMagenta - wavelength_abs)/widthAntiMagenta
nm2RGB(wlcycle700, false)
redvalue_RED = redvalue*bias_RED
bluevalue_RED = bluevalue*bias_RED
greenvalue_RED = greenvalue*bias_RED
-- nm2RGB(wavelength400, false)
redvalue_BLUE = redvalue*bias_BLUE
bluevalue_BLUE = bluevalue*bias_BLUE
greenvalue_BLUE = greenvalue*bias_BLUE
redvalue = 0.6+ 0.4*(redvalue_RED + redvalue_BLUE)
bluevalue = 0.7 + 0.3*(bluevalue_RED + bluevalue_BLUE)
greenvalue = greenvalue_RED + greenvalue_BLUE
end
 
function p.absorption(frame)
-- this function returns the string "#RRGGBB" with approximate RGB value for a complementary color (reflection) to a color, defined as a wavelength passed as a first argument
-- The following formula is used for the complimentary color: {0xFF - RR, 0xFF - (RR + BB)/2, 0xFF - BB}
-- local wavelength = tonumber(frame.args[1])
-- nm2RGB(wavelength)
-- local result='#' .. string.format("%.2X%.2X%.2X", 255*(1-redvalue), 255*(1-greenvalue), 255*(1-bluevalue))
local wavelength = tonumber(frame.args[1])
-- adding magentas to smoothen red->blue transition. Trying 540..570 nm
local redsum = 0
if (wavelength>=minAntiMagenta) and (wavelength<=maxAntiMagenta) then
local greensum = 0
if wlcycle < process_magenta(wavelength then)
local bluesum = 0
else nm2RGB(absorption_to_visible(wavelength), false)
local intensityfactor = 0
local numofitems = 400
for wlcycle = 380,780,1 do
nm2RGB(wlcycle, false)
if wlcycle < wavelength then
intensityfactor = (wlcycle - 380) / (wavelength - 380)
else
intensityfactor = (wlcycle - wavelength) / (380 - wavelength) + 1
end
if intensityfactor < 0 then
intensityfactor = 0
numofitems = numofitems - 1
end
redsum = redsum + redvalue*(intensityfactor*0.3)
greensum = greensum + greenvalue*(intensityfactor*0.59)
bluesum = bluesum + bluevalue*(intensityfactor*0.11)
end
local result='#' .. string.format("%.2X%.2X%.2X", 255*(1-redsum/numofitems)redvalue, 255*(1-greensum/numofitems)greenvalue, 255*(1-bluesum/numofitems)bluevalue)
return result
end
 
 
return p