0

This formula works perfectly for obtaining Lightness and Saturation from an X/Y position within a rectangle. (Thanks to Collin Henderson.)

let hsv_value = 1 - (posy / 100);
let hsv_saturation = posx / 100;
let lightness = (hsv_value / 2) * (2 - hsv_saturation);
let saturation = (hsv_value * hsv_saturation) / (1 - Math.abs(2 * lightness - 1));

However, when I try to plot the value within the rectangle based on existing values I fail trying to reverse the above. I am currently of the opinion the formula is only good one way, but how would I set the value?

My original plan was to use the Saturation and Lightness values as the X and Y but clearly this is wrong. Based on the formula it shouldn't be difficult to create but I have spent far too long on this problem

Original post Get HSL value, given x,y, and hue

atat
  • 19
  • 4

1 Answers1

1

Using Mathematica I get the following solution to the system of two equations:

  • if 2 * lightness - 1 < 0: posx = (200 * saturation)/(1 + saturation), posy = 100 * (1 - lightness * (1 + saturation))
  • else: posx = -200 * (lightness - 1) * saturation / (lightness + saturation - lightness * saturation), posy = 100 * (lightness - 1) * (saturation - 1).

In javascript, with testing:

function test(posx, posy){
   //OP direct formula
   let hsv_value = 1 - (posy / 100);
   let hsv_saturation = posx / 100;
   let lightness = (hsv_value / 2) * (2 - hsv_saturation);
   let saturation = (hsv_value * hsv_saturation) / (1 - Math.abs(2 * lightness - 1));
   
   //inverse formula:
   const [posx_inv, posy_inv] = (2 * lightness - 1 < 0) ?
      [ (200 * saturation) / (1 + saturation), 
      100 * (1 - lightness * (1 + saturation))] :
      [ -200 * (lightness - 1) * saturation / (lightness + saturation - lightness * saturation),
        100 * (lightness - 1) * (saturation - 1)];
   
   console.log('initial data:', {posx, posy});
   //console.log({lightness, saturation});
   console.log('solution:', {posx_inv, posy_inv});
}

//test(10, 40)
test(100*Math.random(), 100*Math.random())
kikon
  • 3,670
  • 3
  • 5
  • 20