3

I am trying to modify the standard HSV Hue color code that ranges from 0 - 360 to one that ranges from 0 – 255. The Saturation and Brightness that range from 0 – 100 do not need to be modified only the Hue.

I need to modify the Hue range so it can be used in my Arduino program with slide controls to control some LED’s. The Arduino program uses a special FastLed library with a modified HSV Hue chart (0 – 255)

I have nowhere near the math skills to figure it out, because of the way the modified color chart works.

Fore example: On the standard HSV chart: 60 = Yellow, 120 = Green, 240 = Blue and 300 = Purple.

On the modified chart: 64 = Yellow, 96 = Green, 160 = Blue and 192 = Purple, and so on.

Here is the standard Hue chart: standard chart

Here is the modified Hue chart: modified chart

Here is the code I have to convert the Standard chart to RGB: (the slider sends a “h” value from 0 – 359) as stated I need this to work with a slider that sends a value from 0 – 255)

function ConvertHSVtoRGB(h,s,v) {
var r,g,b;
var c,x;
c = v*s;

if (h < 120) {x = h/60;} else { if (h < 240) {x = (h-120)/60;} else {x = (h-240)/60;} }

x = c * (1-Math.abs(x-1)); x += (v-c);

switch (Math.floor(h/60)) { case 0: r = v; g = x; b = v-c; break; case 1: r = x; g = v; b = v-c; break; case 2: r = v-c; g = v; b = x; break; case 3: r = v-c; g = x; b = v; break; case 4: r = x; g = v-c; b = v; break; case 5: r = v; g = v-c; b = x; break; }

setRGBColor(r, g, b); }

function setRGBColor(r,g,b) { r = Math.max(0, Math.min(255, Math.round(r255))); g = Math.max(0, Math.min(255, Math.round(g255))); b = Math.max(0, Math.min(255, Math.round(b*255))); }

I would greatly appreciate if anyone can figure out the math needed to help me modify the code.

Thank you for taking the time to read my post, Mike.

Thank you Joriki.

mike
  • 33
  • Does this help? https://math.stackexchange.com/questions/556341/rgb-to-hsv-color-conversion-algorithm It's in the opposite direction, but it might give you some ideas while you wait for answers. – Doug Deden Jan 10 '24 at 21:22
  • Thanks Doug, I took a look but I really cant figure it out, I suck at math. – mike Jan 10 '24 at 21:29

1 Answers1

0

That’s a weird transform – there are two different scales, one near red and another near aqua. You can use this to transform the values (where $m$ is the modified value and $s$ is the standard value):

$$ m= \begin{cases} \frac{64}{60}s&s\le60\;,\\ \frac{64}{120}(s-60)+64&60\le s\le300\;,\\ \frac{64}{60}(s-300)+192&s\ge300\;, \end{cases} $$

which simplifies to

$$ m= \begin{cases} \frac{16}{15}s&s\le60\;,\\ \frac8{15}s+32&60\le s\le300\;,\\ \frac{16}{15}s-128&s\ge300\;. \end{cases} $$

I’m assuming that your ranges up to $360$ and $255$ weren’t precise and that actually $360$ and $256$ correspond to each other and mark the point where you reach red again. If you really did mean that $360$ should correspond to $255$, you’ll have to modify the transform slightly, but that seems unlikely since it would be a rather impractical encoding.

Here’s JavaScript to implement this function, with some checks that the values you specified are converted correctly:

function m(s) {
  return Math.round ((() => {
    if (s < 0)
        throw "illegal argument";
    if (s <= 60)
        return 16/15 * s;
    if (s <= 300)
      return 8/15 * s + 32;
    if (s <= 360)
      return 16/15 * s - 128;
    throw "illegal argument";
  }) ());
}

console.log (m(60)); console.log (m(120)); console.log (m(240)); console.log (m(300));

joriki
  • 238,052
  • the actual slider range is 0 - 359 not 0 - 360, typo. I am trying to understand your answer as you wrote it, but math skill a limited to basic math, so trying to read it and apply it to my code is hard. – mike Jan 10 '24 at 21:40
  • @mike: Feel free to ask. The inequalities on the right are cases, i.e. use the formula on the left that's on the same line as the inequality that your input value $s$ satisfies. About $359$: Yes, I thought so. Then the formula should be correct. – joriki Jan 10 '24 at 21:44
  • Thank you Joriki, that is very kind of you. I will study it for a while and try to run a few code trials and see what happens. – mike Jan 10 '24 at 21:49
  • Joriki, I don’t understand how read your equations, how do I write 16/15s? Could you show me how add them to the JavaScript? if (h < = 60) {x = ??} Thanks, Mike. – mike Jan 10 '24 at 23:30
  • @mike: I added a JavaScript implementation. – joriki Jan 11 '24 at 04:26
  • 1
    Thank you Joriki, It works perfectly! I had everything right except I was adding instead of multiplying after the division. You taught me a lot about reading math notations and equations and have encouraged me to learn more.

    Thanks again for taking the time to help me, and thanks to all the other posters, who donate their time and effort to help and teach others, and of course thanks Stack Exchange!

    – mike Jan 11 '24 at 13:06