Files
itgmania212121/Themes/_fallback/Scripts/03 HSV.lua
T
2011-06-18 14:09:56 -05:00

261 lines
4.7 KiB
Lua

--[[
functions for using HSV colors in StepMania.
Code adapted from http://www.cs.rit.edu/~ncs/color/t_convert.html
changelog:
v 1
= v1.1 =
* Hue(color, newHue) changed to wrap around for invalid values.
* Desaturate(color, percent) renamed to Saturation(color, percent).
______________________________________________________________________________
xxx: support HSL<->RGB (which is different) too?
http://en.wikipedia.org/wiki/HSV_color_space#Conversion_from_RGB_to_HSL_or_HSV
HSL treats absolute brightness of a color at 0.5 in L, whereas
HSV treats absolute brightness of a color at 1.0 in V.
Saturation is different too.
]]
-- HasAlpha(c)
function HasAlpha(c)
if c[4] then
return c[4]
else
return 1
end
end
-- ColorToHSV(c)
-- Takes in a normal color("") and returns a table with the HSV values.
function ColorToHSV(c)
local r = c[1]
local g = c[2]
local b = c[3]
-- alpha requires error checking sometimes.
local a = HasAlpha(c)
local h = 0
local s = 0
local v = 0
local min = math.min( r, g, b )
local max = math.max( r, g, b )
v = max
local delta = max - min
-- xxx: how do we deal with complete black?
if min == 0 and max == 0 then
-- we have complete darkness; make it cheap.
return {
Hue = 0,
Sat = 0,
Value = 0,
Alpha = a
}
end
if max ~= 0 then
s = delta / max -- rofl deltamax :|
else
-- r = g = b = 0; s = 0, v is undefined
s = 0
h = -1
return {
Hue = h,
Sat = s,
Value = v,
Alpha = 1
}
end
if r == max then
h = ( g - b ) / delta -- yellow/magenta
elseif g == max then
h = 2 + ( b - r ) / delta -- cyan/yellow
else
h = 4 + ( r - g ) / delta -- magenta/cyan
end
h = h * 60 -- degrees
if h < 0 then
h = h + 360
end
return {
Hue = h,
Sat = s,
Value = v,
Alpha = a
}
end
-- HSVToColor(hsv)
-- Converts a set of HSV values to a color. hsv is a table.
-- See also: HSV(h, s, v)
function HSVToColor(hsv)
local i
local f, q, p, t
local r, g, b
local h, s, v
local a
s = hsv.Sat
v = hsv.Value
if hsv.Alpha then
a = hsv.Alpha
else
a = 0
end
if s == 0 then
return { v, v, v, a }
end
h = hsv.Hue / 60
i = math.floor(h)
f = h - i
p = v * (1-s)
q = v * (1-s*f)
t = v * (1-s*(1-f))
if i == 0 then
return { v, t, p, a }
elseif i == 1 then
return { q, v, p, a }
elseif i == 2 then
return { p, v, t, a }
elseif i == 3 then
return { p, q, v, a }
elseif i == 4 then
return { t, p, v, a }
else
return { v, p, q, a }
end
end
-- ColorToHex(c)
-- Takes in a normal color("") and returns the hex representation.
-- Adapted from code in LuaBit (http://luaforge.net/projects/bit/),
-- which is MIT licensed and copyright (C) 2006~2007 hanzhao.
function ColorToHex(c)
local r = c[1]
local g = c[2]
local b = c[3]
local a = HasAlpha(c)
local function hex(value)
value = math.ceil(value)
local hexVals = { 'A', 'B', 'C', 'D', 'E', 'F' }
local out = ""
local last = 0
while(value ~= 0) do
last = math.mod(value, 16)
if(last < 10) then
out = tostring(last) .. out
else
out = hexVals[(last-10)+1] .. out
end
value = math.floor(value/16)
end
if(out == "") then
return "00"
end
return string.format( "%02X", tonumber(out,16) )
end
local rX = hex( scale(r, 0, 1, 0, 255) )
local gX = hex( scale(g, 0, 1, 0, 255) )
local bX = hex( scale(b, 0, 1, 0, 255) )
local aX = hex( scale(a, 0, 1, 0, 255) )
return rX .. gX .. bX .. aX
end
function HSVToHex(hsv)
return ColorToHex( HSVToColor(hsv) )
end
--[[ you should mainly use these functions ]]
-- this is the lazy one; use this when you mean fullly visible
function HSV(h, s, v)
local t = {
Hue = h,
Sat = s,
Value = v,
Alpha = 1
}
return HSVToColor(t)
end
-- here's the proper one
function HSVA(h, s, v, a)
local t = {
Hue = h,
Sat = s,
Value = v,
Alpha = a
}
return HSVToColor(t)
end
function Saturation(color,percent)
local c = ColorToHSV(color)
-- error checking
if percent < 0 then
percent = 0.0
elseif percent > 1 then
percent = 1.0
end
c.Sat = percent
return HSVToColor(c)
end
function Brightness(color,percent)
local c = ColorToHSV(color)
-- error checking
if percent < 0 then
percent = 0.0
elseif percent > 1 then
percent = 1.0
end
c.Value = percent
return HSVToColor(c)
end
function Hue(color,newHue)
local c = ColorToHSV(color)
-- handle wrapping
if newHue < 0 then
newHue = 360 + newHue
elseif newHue > 360 then
--newHue = math.mod(newHue, 360); -- ?? untested
newHue = newHue - 360
end
c.Hue = newHue
return HSVToColor(c)
end;
function Alpha(color,percent)
local c = ColorToHSV(color);
-- error checking
if percent < 0 then
percent = 0.0;
elseif percent > 1 then
percent = 1.0;
end;
c.Alpha = percent;
return HSVToColor(c);
end;