Quick actions

cmd+k|ctrl+k

Navigation

Languages

hsv to rgb with rational numbers

Snippet info

Language

Lua

Visibility

public

Author

evine

Created

2017-06-29T11:36:50Z

Updated

2017-06-30T12:26:17Z

function mulRat(op1n, op1d, op2n, op2d)
    return op1n * op2n, op1d * op2d
end

function divRat(op1n, op1d, op2n, op2d)
    return op1n * op2d, op1d * op2n
end

function subRat(op1n, op1d, op2n, op2d)
    return op1n * op2d - op2n * op1d, op1d * op2d    
end

function addRat(op1n, op1d, op2n, op2d)
    return op1n * op2d + op2n * op1d, op1d * op2d    
end

function hsvRational(hn, hd, sn, sd, vn, vd)
    if sn == 0 then
        local rn, rd = mulRat(vn, vd, 255, 1)
        local result = rn / rd
        return result, result, result
    end
    
    local h1n, h1d = mulRat(hn, hd, 6, 1)
    
    local index = math.floor(h1n / h1d)
	local fn, fd = subRat(h1n, h1d, index, 1)
	
    local p1n, p1d = subRat(1, 1, sn, sd)
    local pn , pd  = mulRat(vn, vd, p1n, p1d)
    
    local q1n, q1d = mulRat(sn, sd, fn, fd)
    local q2n, q2d = subRat(1, 1, q1n, q1d)
    local qn , qd  = mulRat(vn, vd, q2n, q2d)
    
    local t1n, t1d = subRat(1, 1, fn, fd)
    local t2n, t2d = mulRat(sn, sd, t1n, t1d)
    local tn,  td  = subRat(1, 1, t2n, t2d)
    
    local r1n,r1d,g1n,g1d,b1n,b1d
    if index == 0 then
		r1n,r1d,g1n,g1d,b1n,b1d = vn,vd,tn,td,pn,pd
	elseif index == 1 then
		r1n,r1d,g1n,g1d,b1n,b1d = qn,qd,vn,vd,pn,pd
	elseif index == 2 then
		r1n,r1d,g1n,g1d,b1n,b1d = pn,pd,vn,vd,tn,td
	elseif index == 3 then
		r1n,r1d,g1n,g1d,b1n,b1d = pn,pd,qn,qd,vn,vd
	elseif index == 4 then
		r1n,r1d,g1n,g1d,b1n,b1d = tn,td,pn,pd,vn,vd
	else
		r1n,r1d,g1n,g1d,b1n,b1d = vn,vd,pn,pd,qn,qd
	end
	
	local rn, rd = mulRat(r1n, r1d, 255, 1)
	local gn, gd = mulRat(g1n, g1d, 255, 1)
	local bn, bd = mulRat(b1n, b1d, 255, 1)

	return rn/rd, gn/gd, bn/bd
end

function hsv(h,s,v,a)
	assert(type(h) == "number" and type(s) == "number" and type(v) == "number" , 
		"heart.hsv(h,s,v) values is not passed in as numbers")
	
	--s = math.clamp(s,0,1)
	--v = math.clamp(v,0,1)

	a = a or 1

	if s == 0 then
		return v*255,v*255,v*255,a*255
	end

	h = h / 60 % 6

	local index = math.floor(h)
	local f = h - index
	local p = v * ( 1 - s )
	local q = v * ( 1 - s * f )
	local t = v * ( 1 - s * ( 1 - f ) )

	local r,g,b
	if index == 0 then
		r,g,b = v,t,p
	elseif index == 1 then
		r,g,b = q,v,p
	elseif index == 2 then
		r,g,b = p,v,t
	elseif index == 3 then
		r,g,b = p,q,v
	elseif index == 4 then
		r,g,b = t,p,v
	else
		r,g,b = v,p,q
	end

	return r*255,g*255,b*255,a*255
end

for i = 0, 1530 - 1 do
    local r1, g1, b1 = hsvRational(i,1530,1,1,1,1)
    local r2, g2, b2 = hsv(i / 4.25,1,1,1)
    print("Index "..i)
    print(r1, g1, b1)
    print(r2, g2, b2)
    print(
        r1 == r2 and "" or "Red Diff",
        g1 == g2 and "" or "Grenn Diff",
        b1 == b2 and "" or "Blue Diff")
end

INFO