If I had RGB values: 255, 165, 0
, what could be done to calculate the analogous color(s) of 218, 255, 0
and 255, 37, 0
, but still appl
Converting from RGB to HSL and rotating +/- 30 degrees might be indeed what you want, but you will not get the color wheel showed. Obtaining, respectively, 12 and 128 colors, starting with pure red (at top), this is what you will get:
And here is sample code to produce the analogous colors:
import colorsys
DEG30 = 30/360.
def adjacent_colors((r, g, b), d=DEG30): # Assumption: r, g, b in [0, 255]
r, g, b = map(lambda x: x/255., [r, g, b]) # Convert to [0, 1]
h, l, s = colorsys.rgb_to_hls(r, g, b) # RGB -> HLS
h = [(h+d) % 1 for d in (-d, d)] # Rotation by d
adjacent = [map(lambda x: int(round(x*255)), colorsys.hls_to_rgb(hi, l, s))
for hi in h] # H'LS -> new RGB
return adjacent
The other color wheel was obtained by considering a subtractive color system. For that, let us consider the RYB color space for simplicity (it represents the color mixing you probably learned in your art classes in any typical school). By using it, we immediately obtain the following wheels:
To obtain these analogous colors, we consider a color in RGB to directly represent a color in RYB, and then convert from RYB to RGB. For example, suppose you have a triple (255, 128, 0) in RGB. Call that triple a RYB triple and convert to RGB to obtain (255, 64, 0). This RYB -> RGB conversion is not unique in the sense that there might be multiple definitions for it, I've used the one from "Paint Inspired Color Compositing" by Gosset and Chen. Here is the code to perform the conversion:
def _cubic(t, a, b):
weight = t * t * (3 - 2*t)
return a + weight * (b - a)
def ryb_to_rgb(r, y, b): # Assumption: r, y, b in [0, 1]
# red
x0, x1 = _cubic(b, 1.0, 0.163), _cubic(b, 1.0, 0.0)
x2, x3 = _cubic(b, 1.0, 0.5), _cubic(b, 1.0, 0.2)
y0, y1 = _cubic(y, x0, x1), _cubic(y, x2, x3)
red = _cubic(r, y0, y1)
# green
x0, x1 = _cubic(b, 1.0, 0.373), _cubic(b, 1.0, 0.66)
x2, x3 = _cubic(b, 0., 0.), _cubic(b, 0.5, 0.094)
y0, y1 = _cubic(y, x0, x1), _cubic(y, x2, x3)
green = _cubic(r, y0, y1)
# blue
x0, x1 = _cubic(b, 1.0, 0.6), _cubic(b, 0.0, 0.2)
x2, x3 = _cubic(b, 0.0, 0.5), _cubic(b, 0.0, 0.0)
y0, y1 = _cubic(y, x0, x1), _cubic(y, x2, x3)
blue = _cubic(r, y0, y1)
return (red, green, blue)