HSV to RGB solution

General discussion about LÖVE, Lua, game development, puns, and unicorns.
SliiX
Prole
Posts: 12
Joined: Mon Apr 13, 2020 9:04 am

HSV to RGB solution

Post by SliiX »

Hello! I have been working on a different method for converting HSV to RGB and I figured I would share it.
I was also wonder if there was a solution to shifting 3 return values other than using that if-statement block at the bottom?

Code: Select all

local ceil = math.ceil
local abs = math.abs

local function clamp(v, min, max)
    if v < min then return min end
    if v > max then return max end

    return v
end

function HSV(h, s, v)
    local vert = ceil(h / 120)
    local rat = abs(((h / 60) - 2 * vert))
    
    -- arc to vertex ratios along with extra channel
    local r, g, b = clamp(rat, 1 - s, 1), clamp(2 - rat, 1 - s, 1), (1 - s * v)
    
    -- vertex shift
    if vert == 1 then return r, g, b end
    if vert == 2 then return b, r, g end
    if vert == 3 then return g, b, r end
end
User avatar
darkfrei
Party member
Posts: 1197
Joined: Sat Feb 08, 2020 11:09 pm

Re: HSV to RGB solution

Post by darkfrei »

Code: Select all

r, g, b = vert==1 and r,g,b or vert==2 and b,r,g or g,b,r
return r, g, b
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: HSV to RGB solution

Post by ReFreezed »

darkfrei wrote: Fri Mar 04, 2022 8:15 am (nonsense)
My hand went straight through my head when I facepalmed.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: HSV to RGB solution

Post by pgimeno »

Code: Select all

r, g, b = select(4 - vert, g, b, r, g, b)
return r, g, b
However, select() breaks traces, so it's not very recommended. The `if` version will probably perform better. I'd remove the last `if`, though: assume that if it's not 1 or 2, it must be 3.

Also, clamp() could be improved:

Code: Select all

local min, max = math.min, math.max

local function clamp(v, vmin, vmax)
  return min(max(v, vmin), vmax)
end
which compiles to faster code.
User avatar
darkfrei
Party member
Posts: 1197
Joined: Sat Feb 08, 2020 11:09 pm

Re: HSV to RGB solution

Post by darkfrei »

Maybe also the
h = h%360
for some situations, where h can be any value as
h = h + dt to change the hue by the time.
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
SliiX
Prole
Posts: 12
Joined: Mon Apr 13, 2020 9:04 am

Re: HSV to RGB solution

Post by SliiX »

darkfrei wrote: Fri Mar 04, 2022 8:15 am

Code: Select all

r, g, b = vert==1 and r,g,b or vert==2 and b,r,g or g,b,r
return r, g, b
that is quite an interesting solution, I might try that. Although I think the if statements are easier on the eyes personally.
Also broke when shifting to vertex 2
Last edited by SliiX on Sat Mar 05, 2022 12:15 am, edited 1 time in total.
SliiX
Prole
Posts: 12
Joined: Mon Apr 13, 2020 9:04 am

Re: HSV to RGB solution

Post by SliiX »

pgimeno wrote: Fri Mar 04, 2022 12:43 pm

Code: Select all

r, g, b = select(4 - vert, g, b, r, g, b)
return r, g, b
However, select() breaks traces, so it's not very recommended. The `if` version will probably perform better. I'd remove the last `if`, though: assume that if it's not 1 or 2, it must be 3.

Also, clamp() could be improved:

Code: Select all

local min, max = math.min, math.max

local function clamp(v, vmin, vmax)
  return min(max(v, vmin), vmax)
end
which compiles to faster code.
That select function is an interesting take, but, it broke on the second vertex, and on the third it didn't return one of the color values.
Also I already tried that clamp function, and the min/max method appears to be slightly slower when I timed it.
SliiX
Prole
Posts: 12
Joined: Mon Apr 13, 2020 9:04 am

Re: HSV to RGB solution

Post by SliiX »

I realized I forgot to incorporate the value, I also made some slight changes.

Code: Select all

local ceil = math.ceil
local abs = math.abs

local function clamp(v, min, max)
    if v < min then return min end
    if v > max then return max end

    return v
end

function HSV(h, s, v)
    v = v or 1; s = (1 - s) * v or 0

    local vert = ceil(h / 120)
    local rat = abs((h / 60) - 2 * vert)

    -- arc to vertex ratios along with extra channel
    local r, g = clamp(rat * v, s, 1), clamp((2 - rat) * v, s, 1)

    -- vertex shift
    if vert == 1 then return r, g, s end
    if vert == 2 then return s, r, g end
    return g, s, r
end
User avatar
darkfrei
Party member
Posts: 1197
Joined: Sat Feb 08, 2020 11:09 pm

Re: HSV to RGB solution

Post by darkfrei »

We can use the zigzag function (but with clamp):
2020-09-20T10_56_25-zigzag.png
2020-09-20T10_56_25-zigzag.png (84.55 KiB) Viewed 4947 times
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
zorg
Party member
Posts: 3465
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: HSV to RGB solution

Post by zorg »

SliiX wrote: Sat Mar 05, 2022 12:04 am
darkfrei wrote: Fri Mar 04, 2022 8:15 am

Code: Select all

r, g, b = vert==1 and r,g,b or vert==2 and b,r,g or g,b,r
return r, g, b
that is quite an interesting solution, I might try that. Although I think the if statements are easier on the eyes personally.
Also broke when shifting to vertex 2
I think it broke because it wasn't parenthesized correctly; this might be better:

Code: Select all

r, g, b = vert==1 and r,g,b or (vert==2 and b,r,g or g,b,r)
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest