views:

476

answers:

4

I am looking for an algorithm that will generate a series of colors so that the colors will be as widely distributed as possible (so they won't easily be mixed up).

I have a series of objects that have IDs that count up from 1. I would like to represent each of these with a different, aesthetically pleasing, color that won't get easily confused with its neighbors. The colors should not necessarily be random though. I would like to get the same color each time I input the same ID.

+1  A: 

Try having a look to Color Lists, NSColorList.

IlDan
+2  A: 

Does the number of possible elements have a reasonable low bound? One quick and easy solution is to just store an array of color values using the ID of the item. That assumes that you have a relatively low amount of colors, and you're certain that you won't go above a certain number of items, however.

If you want to generate colors rather than use a list, one trick to make them have a consistent and decent look is to generate them using HSB. Pre-define a brightness and saturation, then base the hue value off some function of the ID (this can be a variety of things depending on how many IDs you plan to have, but multiplying the ID by some amount (and modding when it exceeds 255!) is a good rough approach. With this approach the colors will all "align" in terms of saturation and brightness but they'll each have a distinct color.

I'm a bit bored at work, so I whipped together a fast solution:

class HsbColor
{
    public int Hue { get; set; }
    public int Saturation { get; set; }
    public int Brightness { get; set; }

    public Color ToRGB
    {
        // left as exercise to the reader...
    }
}

public class Item
{


    public int Id { get; set; }
    private static const byte EXPECTED_MAX = 15;
    private static int HUE_FACTOR = 255 / EXPECTED_MAX;

    public HsbColor Color 
    {
       get {

         var color = new HsbColor() { Saturation = 175, Brightness = 175 };

         color.Hue = (Id * HUE_FACTOR) % 255;

         return color;
       }
    }
}
Ryan Brunner
See my answer for a way to avoid predicting the EXPECTED_MAX and still get an even distribution.
Patrick McElhaney
+5  A: 

You can multiply the id by the golden angle to get a number 0 <= n < 1. All of the numbers you generate will tend to be evenly distributed.

golden_angle = 0.381966 
angle_for_id = id * golden_angle
n = angle_for_id - floor(angle_for_id)

Then it's a matter of converting that number to a color, e.g.

hue = floor(n * 256)
Patrick McElhaney
+3  A: 
Norman Ramsey