Module:Sandbox/AlexNB/nmColor
local p = {}
local redvalue = 0
local greenvalue = 0
local bluevalue = 0
local function nm2RGB(wavelength, IFcorrect)
-- code based on an algorithm from Dan Bruton's Color Science Page: http://www.physics.sfasu.edu/astro/color/spectra.html
-- calculating RGB color components
if (wavelength >= 380) and (wavelength < 440) then
redvalue = (440 - wavelength) / 90
greenvalue = 0
bluevalue = 1
elseif (wavelength >= 440) and (wavelength < 490) then
redvalue = 0
greenvalue = (wavelength - 440) / 50
bluevalue = 1
elseif (wavelength >= 490) and (wavelength < 510) then
redvalue = 0
greenvalue = 1
bluevalue = (510 - wavelength) / 20
elseif (wavelength >= 510) and (wavelength < 580) then
redvalue = (wavelength - 510) / 70
greenvalue = 1
bluevalue = 0
elseif (wavelength >= 580) and (wavelength < 645) then
redvalue = 1
greenvalue = (645 - wavelength) / 65
bluevalue = 0
elseif (wavelength >= 645) and (wavelength <= 780) then
redvalue = 1
greenvalue = 0
bluevalue = 0
end
-- calculating intensity correction factor
if IFcorrect then
local intensityfactor = 0
if (wavelength >= 380) and (wavelength < 420) then
intensityfactor = 0.3 + 0.7*(wavelength - 350) / 70
elseif (wavelength >= 420) and (wavelength <= 700) then
intensityfactor = 1
elseif (wavelength > 700) and (wavelength <= 780) then
intensityfactor = 0.3 + 0.7*(780 - wavelength) / 80
end
redvalue = redvalue * intensityfactor
greenvalue = greenvalue * intensityfactor
bluevalue = bluevalue * intensityfactor
end
end
function p.emission(frame)
-- this function returns the string "#RRGGBB" with approximate RGB value for a wavelength passed as a first argument
local wavelength = tonumber(frame.args[1])
nm2RGB(wavelength, true)
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 minBlue = 430
local maxBlue = 490
local widthBlue = maxBlue - minBlue
local minGreen = 490
local maxGreen = 560
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(700, false)
redvalue_RED = redvalue*bias_RED
bluevalue_RED = bluevalue*bias_RED
greenvalue_RED = greenvalue*bias_RED
nm2RGB(400, 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
local wavelength = tonumber(frame.args[1])
-- adding magentas to smoothen red->blue transition. Trying 540..570 nm
if (wavelength>=minAntiMagenta) and (wavelength<=maxAntiMagenta) then
process_magenta(wavelength)
else nm2RGB(absorption_to_visible(wavelength), false)
end
local result='#' .. string.format("%.2X%.2X%.2X", 255*redvalue, 255*greenvalue, 255*bluevalue)
return result
end
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.