0

I have a OpenGL application that renders a 3d object. I would like the user of the application choose a color for the 3D object and I would like to automatically generate a complementary background color for it. Are there any well known algorithms or techniques to get this done ?

vishpat
  • 133
  • 1
  • 7

1 Answers1

2

The complement of a color is usually defined as one whose hue is shifted 180 degrees. In pseudocode, this is what you're looking for:

function complement(rgbColor)
{
    local hslColor = rgbToHsl(rgbColor)
    hslColor.h += 180.0
    hslColor.h %= 360.0

    return hslToRgb(hslColor)
}

Many libraries include helper functions for converting between RGB and HSL and/or HSV/HSB color spaces. Otherwise, take a look here to see about implementing these functions yourself.

Note that HSL and HSV/HSB are not the same, but the hue is defined the same either way, so it doesn't really matter which you use in this case. It's also worth noting that the hues defined on a painter's color wheel are distributed slightly differently than in HSL/HSV/HSB.

If there's a possibility that you might need to deal with desaturated colors (aka grayscale) then this function will output the same shade as was input. One possible way to work around this would be to invert the lightness as well as shifting the hue. This means black will become white, light gray will become dark gray, etc. The only problem then is 50% gray, which will remain 50% gray. If that's a problem, you could add 50% to the saturation if it is less than 50%. For perfectly monochromatic colors (r = b = g) most RGB-to-HSL converters will report a hue of 0 (red), so this will result in 50% gray transforming into a dull-red color. Note that these workarounds assume that you're using HSL, not HSV/HSB.

function getContrastingColor(rgbColor)
{
    local hslColor = rgbToHsl(rgbColor)
    hslColor.h += 180.0
    hslColor.h %= 360.0

    hslColor.l = 1.0 - hslColor.l

    if (hslColor.s < 0.5)
        hslColor.s += 0.5

    return hslToRgb(hslColor)
}
Community
  • 1
  • 1
bcrist
  • 1,520
  • 13
  • 25
  • Wouldn't this give the same color as output if the input is a grayscale value? So if the OP is looking for something that gives a visually different color no matter what the input color is, I don't think this would work for all cases. – Reto Koradi Aug 10 '14 at 02:00
  • @RetoKoradi Yes, desaturated colors may be problematic. Color theory generally defines "complementary color" to be one which differs only in hue. Otherwise, "contrasting color" might be a better description. I've updated the answer with some potential workarounds. – bcrist Aug 10 '14 at 02:19