The following is a brief description of our initial approach to solving this problem. You can find our sample app, ColourPalette, on GitHub.
Our Sample Application
Launching ColourPalette reveals a number of different controls that can be effected to change each set of colors (i.e., palette).
H, S, & V controls the Hue, Saturation, & Value.
L, A, B & ∆ sliders control the distance vector for each dimension in the CEILAB colourspace
The heuristic for our palette generation is admitedly a bit crude, but dealing with color palette generation is never an exact science.
Our algorithm works by taking a seed color, translating it into CIELAB colorspace, and then bounding it by a randomly derived (from the delta values above) mini-ellipsoid. It then generates random points within that ellipsoid until it acquires a valid neighbor color.
The guts of this can be seen in our file ColorPaletteGenerator.m:
CGFloat lambda_neg = (0 == arc4random() % 2) ? 1.0f : -1.0f;
CGFloat beta_neg = (0 == arc4random() % 2) ? 1.0f : -1.0f;
CGFloat lambda = ((CGFloat)arc4random() / (CGFloat)RAND_MAX) * M_PI * lambda_neg;
CGFloat beta = ((CGFloat)arc4random() / (CGFloat)RAND_MAX) * M_PI_2 * beta_neg;
x = aX * cos(beta) * cos(lambda);
y = aY * cos(beta) * sin(lambda);
z = bZ * sin(beta);
It’s possible to derive colors that sit outside the spectrum of sRGB so this method is implemented asynchronously so that it can loop and filter results until it determines matches for the ∆ value.
But forget all the math — just give it a try!
Be sure to grab the sample project on GitHub. It leverages thirteen23's T23Kit-Colour cocoapod to generate our unique color palettes. For more on this library, also see “T23 Color Kit: Mixing Colors Like an Artist.”