Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort Colors (Objective-C)

I'm doing this sort of thing:

- (NSArray*)colors {
    float divisor = .3333;
    NSMutableArray *retVal = [NSMutableArray array];
    for (float one=0; one <= 1.0f; one += divisor) {
        for (float two = 0; two <= 1.0f; two += divisor) {
            for (float three = 0; three <= 1.0f; three += divisor) {
                UIColor *color = [UIColor colorWithRed:one green:two blue:three alpha:.5];
                // also bad
                // UIColor *color = [UIColor colorWithHue:one saturation:two brightness:three alpha:.5];
                [retVal addObject:color];
            }
        }
    }
    return retVal;
}

and, as I suspected, the colors come out horribly out of order (to the eye). The reds are not with the reds, purples not with the purples, etc.

Is there no easy way to create a list of diverse colors, nicely grouped according to human criteria like, "that looks blue?"

like image 205
Dan Rosenstark Avatar asked Dec 21 '11 04:12

Dan Rosenstark


2 Answers

This worked quite well. It will NOT help the fact that you have a lot of repeated colors. See below:

NSArray *sorted = [[dict allValues] sortedArrayUsingComparator:^NSComparisonResult(UIColor* obj1, UIColor* obj2) {
    float hue, saturation, brightness, alpha;
    [obj1 getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha];
    float hue2, saturation2, brightness2, alpha2;
    [obj2 getHue:&hue2 saturation:&saturation2 brightness:&brightness2 alpha:&alpha2];
    if (hue < hue2)
        return NSOrderedAscending;
    else if (hue > hue2)
        return NSOrderedDescending;

    if (saturation < saturation2)
        return NSOrderedAscending;
    else if (saturation > saturation2)
        return NSOrderedDescending;

    if (brightness < brightness2)
        return NSOrderedAscending;
    else if (brightness > brightness2)
        return NSOrderedDescending;

    return NSOrderedSame;
}];

You can access the components (HSBA) like this in iOS 4.x:

    CGFloat *components = (CGFloat *)CGColorGetComponents([color CGColor]);
    float hue = components[0];
    float saturation = components[1]; // etc. etc.

To avoid repeating colors: you can put the elements in an NSMutableDictionary, keyed on something like their hue-saturation-brightness (each rounded to the nearest .10)... then you get the array from THAT, and then sort.

like image 121
Dan Rosenstark Avatar answered Nov 08 '22 03:11

Dan Rosenstark


I think using [UIColor colorWithHue:saturation: brightness: alpha:] is your best bet. If you fix saturation, brightness and alpha and just use Hue you'll get all the colours in order.

Check out the wiki for HSB for more information.

for (float hsb = 0; hsb <= 1.0f; hsb += divisor) {
             UIColor *color = [UIColor colorWithHue:hsb saturation:1.0f brightness:1.0f alpha:.5f];
            [retVal addObject:color];
}
like image 39
thelaws Avatar answered Nov 08 '22 05:11

thelaws