Page 1 of 3
HSV to RGB solution
Posted: Fri Mar 04, 2022 2:01 am
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
Re: HSV to RGB solution
Posted: Fri Mar 04, 2022 8:15 am
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
Re: HSV to RGB solution
Posted: Fri Mar 04, 2022 9:45 am
by ReFreezed
darkfrei wrote: ↑Fri Mar 04, 2022 8:15 am
(nonsense)
My hand went straight through my head when I facepalmed.
Re: HSV to RGB solution
Posted: Fri Mar 04, 2022 12:43 pm
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.
Re: HSV to RGB solution
Posted: Fri Mar 04, 2022 1:55 pm
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.
Re: HSV to RGB solution
Posted: Sat Mar 05, 2022 12:04 am
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
Re: HSV to RGB solution
Posted: Sat Mar 05, 2022 12:06 am
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.
Re: HSV to RGB solution
Posted: Sat Mar 05, 2022 12:43 am
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
Re: HSV to RGB solution
Posted: Sat Mar 05, 2022 9:24 am
by darkfrei
We can use the zigzag function (but with clamp):
- 2020-09-20T10_56_25-zigzag.png (84.55 KiB) Viewed 4946 times
Re: HSV to RGB solution
Posted: Sat Mar 05, 2022 10:07 am
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)