-- Returns an RBG color from a hue value and an intensity value

----------------------------------------------------------------------------------------------------------------------

-- @param angle hue value from 0 to 2 * Math.pi (ideally, going beyond that range will yeild unexpected results)

-- @param intensity brightness value from 0 to 1 (ideally. Going beyond that range will also yield unexpected results)

----------------------------------------------------------------------------------------------------------------------

function hue_to_rgb ( angle , intensity )

if hue < math.pi / 3 then

local diff = hue / ( math.pi / 3 )

return { intensity , intensity * diff , 0 }

elseif hue < 2 * math.pi / 3 then

local diff = ( hue - math.pi / 3 ) / ( math.pi / 3 )

return { intensity * ( 1 - diff ) , intensity , 0 }

elseif hue < math.pi then

local diff = ( hue - 2 * math.pi / 3 ) / ( math.pi / 3 )

return { 0 , intensity , intensity * diff }

elseif hue < 4 * math.pi / 3 then

local diff = ( hue - math.pi ) / ( math.pi / 3 )

return { 0 , intensity * ( 1 - diff ) , intensity }

elseif hue < 5 * math.pi / 3 then

local diff = ( hue - 4 * math.pi / 3 ) / ( math.pi / 3 )

return { intensity * diff , 0 , intensity }

else

local diff = ( hue - 5 * math.pi / 3 ) / ( math.pi / 3 )

return { intensity , 0 , intensity * ( 1 - diff ) }

end

end

-- Returns a color on a linear gradient at pos distance from color1 between color1 and color2

-------------------------------------------------------------------------------------------------------------

-- @param color1 first color value {r,g,b}

-- @param color2 second color vlue {r,g,b}

-- @param pos distance away from color 1. The distance away from color2 is 1 - pos (should be btween 0 and 1)

-------------------------------------------------------------------------------------------------------------

function color_between ( color1 , color2 , pos )

local color_1_comp = 1 - pos

local color_2_comp = pos

return { color1 [ 1 ] * color_1_comp + color2 [ 1 ] * color_2_comp ,

color1 [ 2 ] * color_1_comp + color2 [ 2 ] * color_2_comp ,

color1 [ 3 ] * color_1_comp + color2 [ 3 ] * color_2_comp }

end

-- Gradient Class

Gradient = { }

Gradient . __index = Gradient

-- Gradient Constructor - A gradient contains a table of different colors that make up the gradient.

----------------------------------------------------------------------------------------------------

-- @param color_table a table containing N colors (a single color is an {r,g,b} color)

----------------------------------------------------------------------------------------------------

function Gradient . new ( color_table )

local self = setmetatable ( { } , Gradient )

self . color_table = color_table

return self

end

-- Gradient Color Selection function - Returns color at position from the gradient

--------------------------------------------------------------------------------------------------------

-- @param self Gradient object

-- @param pos Value between 0 and 1 with 0 being the beginning of the gradient and 1 being the end of it

--------------------------------------------------------------------------------------------------------

function Gradient . getColorAt ( self , pos )

local color_table = self . color_table

local color1 = ( math.floor ( ( ( # color_table - 1 ) * pos ) ) % # color_table ) + 1 --2

local color2 = color1 + 1 --3

-- Trying to go higher is outside the gradient, just return the highest color value --

if color2 > # color_table then

return color_table [ # color_table ]

end

local pos_of_one = ( color1 - 1 ) / ( # color_table - 1 ) --

local pos_from_one = ( pos - pos_of_one ) * ( # color_table - 1 )

return color_between ( color_table [ color1 ] , color_table [ color2 ] , pos_from_one )

end

-- Example Gradient -- hey, guess what, it's the same as the Hue Selector at full intensity!

example_gradient = Gradient . new ( { { 1 , 0 , 0 } , { 1 , 1 , 0 } , { 0 , 1 , 0 } , { 0 , 1 , 1 } , { 0 , 0 , 1 } , { 1 , 0 , 1 } , { 1 , 0 , 0 } } )

-- Another example gradient, cycles from orange to purple to cyan back to orange