sooprise
sooprise

Reputation: 23187

Randomly Generate Unique Colors?

I'm using a graphing package that can draw lines of color (255,255,255). So basically what I'm doing is (Random.Next(0,255),Random.Next(0,255),Random.Next(0,255)) to generate a color each time a line is added.

This is all well and good, but sometimes, I get colors that look very similar, making it difficult for the user to discern which data corresponds to which line.

Is there a more clever way to generate random and unique colors in the (255,255,255) format?

Upvotes: 4

Views: 3478

Answers (8)

RD1
RD1

Reputation: 3325

If the goal is to produce relatively uniformly distributed colours rather than just random, a standard technique is to set the Hue for the nth colour to n * 137 degrees. 137 (ish) is the "golden angle" which has some special properties that lead to a relatively well spaced distribution.

If you also want to vary the saturation and level I suspect that you can do something similar by mapping angles to a limited range and instead of using the golden angle use multiples of it to avoid tight association between the three components. E.g, use ((n * 2 * 137) mod 360)/720.0 + 0.5 for saturation and ((n * 4 * 137) mod 360)/720.0 + 0.25 for the level.

Upvotes: 0

supercat
supercat

Reputation: 81105

Is there any reason to randomize colors, rather than outputting them in a fixed sequence? I would suggest that you use an index which gets incremented each color. Use a constant (probably maximum) saturation for your colors, have lightness be frac(indexconst1) and hue be frac(indexconst2). I'm not sure how best to compute const1 and const2; that will depend in some measure on how many points you'll have.

Upvotes: 0

Mau
Mau

Reputation: 14468

I wrote a utility function once to do that.

The idea was to linearise the RGB space into a 1D [0, 1] interval. For example doing (R + G*256 + B*256*256)/(256^3*256^2+256).

Then, everytime you need a new colour, you split an interval generated by previous samplings in 2. You pick the first colour as 0.0 in the new space, the second as 1.0, the third as 0.5, then 0.25, then 0.75 and so on. This kinda guarantees that if you generate few colours they have maximum 'separation' (though nor measured in terms of hue). As you generate more and more colours, they tend to get closer to one generated before, but always respecting a max-separation principle.

Once you have your [0, 1] value, you use the inverse function (triplet of functions actually) to go back to RGB.

In the basic implementation you get white and black as the two first colours. If you want something different, once you have generated your 'input' [0, 1] value, you can rotate it, say by a third, inside the same interval.

This works pretty well and it behaves deterministically (no unbounded number of retries).

Upvotes: 0

Neil N
Neil N

Reputation: 25258

Check the "color distance"

Assume RGB are XYZ coordinates, do a 3D distance calculation. If a color isn't at least N away from all previously generated colors, try again.

N is a value you decide.

Upvotes: 7

prat
prat

Reputation: 607

assuming difference in shades is a measure of euclidean distance between coordinates, you can
1. Remember the previous color generated (a,b,c)
2. make sure that the next one generated (x,y,z) is atleast more than half the max possible distance
i.e sqrt [(a-x)^2 + (b-y)^2 + (c-z)^2] > 1/2 sqrt (3 * 255^2)
3. keep generating random triplets until you get one that satisfies above.. if 1/2 is not good enough, try 2/3 etc.strong text

Upvotes: 1

phimuemue
phimuemue

Reputation: 35983

Concerning uniqueness, have a look here.

For clearer color differences, you might try not to allow all possible values from 0 to 255, but only some steps, e.g. 0-32-64-96-128-160-192-224-255, so you get a bit of contrast.

Upvotes: 0

Sandor Drieënhuizen
Sandor Drieënhuizen

Reputation: 6388

A very simple solution might be to use more distinct levels by taking ((Random.Next(0, 32) * 8) % 256) for example. Perhaps a lookup table can be used to skip colors that have been used already.

Upvotes: 0

Reed Copsey
Reed Copsey

Reputation: 564363

A better option is to typically generate a random hue, and the convert the hue to an RGB color using an HSL or HSV color (with that hue). By using a random "hue" instead of random color, you'll get much more variation in your colors. You can also randomize the other components (saturation/value, etc), if you need even more variation.

See Wikipedia for details on working in colors using HSV/HSL, including how to convert HSV to RGB.

Upvotes: 13

Related Questions