A Few Possibly Handy Functions - Colour Picker, Conversion, Hex

Posted by Beale on Wed 17 Aug 2005 12:37 AM — 1 posts, 11,313 views.

#0
So, in my quest to make a good colourpicker, I ended up with the code shown below. It contains functions:
colourPicker ( string sCommandHead, string sCommandFoot )
fColourList()
hsltorgb(float hue, float saturation, float lightness)
huetorgb(float param1, float param2, float param3)
int2char(int number)
hex(int number)


I figured someone else might find these handy, for something.

colourPicker depends on all of the above functions, and generates a rather large array (40 x 20, with spaces between) of coloured octothorpes (yes, that's what they're called, not "pound signs" or "hashes" :) ) that link to commands containing their colour between sCommandHead and sCommandFoot.

fColourList generates the large array of colours that colourPicker displays/uses.

hsltorgb does exactly what it says on the tin: turns a HSL colour space colour into an RGB one, preceded by a "#" for ease of use. It depends on huetorgb, since that's the form the algorithm I found when I was looking was in. Note that the HSL colour is expected in fractional components, rather than 1-256 ones.

hex turns a decimal number into a hexidecimal one, and depends on int2char.


function colourPicker( sCommandHead, sCommandFoot )
  local iCount = 1
  local arrColourList = fColourList()
  for k, v in pairs(arrColourList) do
    ColourTell(v, "", "#")
    world.Hyperlink(sCommandHead .. v .. sCommandFoot, " ", v, RGBColourToName(GetNoteColourBack()), "", false)
    Tell("")
    iCount = iCount + 1
    if iCount == 41 then iCount = 1 world.Note("") end
  end
  Note("")
end

function fColourList()
  iIndex = 1
  arrOut = {}
  --Black through White - the first line.
  while iIndex<41 do
    arrOut[iIndex] = hsltorgb(0, 0, iIndex/40)
    iIndex = iIndex + 1
  end
  local hue = 0
  local sat = 1
  local light = 0
  --The Rest - increment hue, go from dark to light, repeat.
  while hue<=1 do
    light = 0
    while light<=1 do
      arrOut[iIndex] = hsltorgb(hue, sat, light)
      light = light + (1/40)
      iIndex = iIndex + 1
    end
    hue = hue + (1/20)
  end
  return arrOut
end

function hsltorgb(h, s, l)
	if l<=0.5 then
		m2=l*(s+1)
	else 
		m2=l+s-l*s
	end
	m1=l*2-m2
	r=huetorgb(m1, m2, h+1/3)
	g=huetorgb(m1, m2, h    )
	b=huetorgb(m1, m2, h-1/3)
	r=math.floor(r*255)
	g=math.floor(g*255)
	b=math.floor(b*255)
  
	sOut = "#"
        if r<16 then sOut = sOut .. "0" .. hex(r) else sOut = sOut .. hex(r) end
	if g<16 then sOut = sOut .. "0" .. hex(g) else sOut = sOut .. hex(g) end
	if b<16 then sOut = sOut .. "0" .. hex(b) else sOut = sOut .. hex(b) end
	return sOut
end

function huetorgb(m1, m2, h)
  if h<0 then h=h+1 end
  if h>1 then h=h-1 end
  if h*6<1 then return m1+(m2-m1)*h*6 end
  if h*2<1 then return m2 end
  if h*3<2 then return m1+(m2-m1)*(2/3-h)*6 end
  return m1
end

function int2char(a)
if a >  16 then return nil end
if a == 15 then return 'F' end
if a == 14 then return 'E' end
if a == 13 then return 'D' end
if a == 12 then return 'C' end
if a == 11 then return 'B' end
if a == 10 then return 'A' end
return a
end

function hex(a)
iIn = tonumber(a)
if iIn == 0 then return "0" end
iLoop = 1
sOut=""
while iIn > 0 do
	iChar = math.mod(iIn,16^iLoop)/(16^(iLoop-1))
	--world.Note(iChar)
	iIn = iIn - math.mod(iIn,16^iLoop)
	sOut = int2char(iChar) .. sOut 
	iLoop = iLoop + 1
end
return sOut
end