Search code examples
mathcolorsinterpolationrgbcolor-wheel

Determining the RYB complement of a color


I am attempting to get the color harmonies of a color in RYB space. I have successfully implemented RGB harmonies, but cannot get RYB harmonies to work properly. They are off by FAR.

My program gets a HEX/HTML color, converts it to RGB, converts the RGB to RYB, converts the RYB to HSL, and performs the harmony calculations from there by incrementing the hue. I used the formulas on https://www.rapidtables.com/convert/color/rgb-to-hsl.html to convert the RYB to HSL. On that page, it gives the formula to convert RGB to HSL. I just use the RYB values in place of the RGB. Below is the formula I use to convert RGB to RYB:

var r = color[0], g = color[1], b = color[2];

// Remove the whiteness from the color.

var w = Math.min(r, g, b);

r -= w;

g -= w;

b -= w;



var mg = Math.max(r, g, b);



// Get the yellow out of the red+green.

var y = Math.min(r, g);

r -= y;

g -= y;



// If this unfortunate conversion combines blue and green, then cut each in

// half to preserve the value's maximum range.

if (b && g) {

    b /= 2.0;

    g /= 2.0;

}



// Redistribute the remaining green.

y += g;

b += g;



// Normalize to values.

var my = Math.max(r, y, b);

if (my) {

    var n = mg / my;

    r *= n;

    y *= n;

    b *= n;

}



// Add the white back in.

r += w;

y += w;

b += w;



// And return back the ryb typed accordingly.

return [r, y, b];

}

When getting the complementary color of Red in RYB, it should be a green. When getting the complementary color of Red in RGB, it should be cyan. My program gives cyan no matter what. The program should give me this: http://prntscr.com/o16ava Instead, it gives me: http://prntscr.com/o16b08


Solution

  • It's not working correctly because, as you mentioned in your comments, you are treating the ryb as if it was rgb when you convert it to hsl.

    When you run the code posted above with the values : red = 255, green = 0, blue = 0

    It returns the values : red = 255, yellow = 0, blue = 0

    Taking the compliment : red = 0, yellow = 255, blue = 255

    If you then pass this into a function designed to convert rgb into hsl, it's going to calculate it as if you were telling it to convert : red = 0, green = 255, blue = 255

    Which is cyan.

    You need to either convert back from ryb to rgb or get a function that is designed to convert ryb into hsl.