1

My goal is to generate some unique random colors that can be easily seen by people. It means i try to avoid having both of ocean blue and sky blue. I prefer having violet red and ocean blue.

I think i need to have a variable that will be a "gap" between any generated RGB. For example, if the gap is 60 then the first and second color cant be RGB(12,27,38) and RGB(45,102,177) because the difference in red value is lesser than 60. (45-12=33).

This is what i tried so far :

int temp;

        for(int i = 0; i < size; i++)
        {
            Rectangle r = new Rectangle();
            temp = COLOR_LIMIT - colourGap;

            if(i == 0 || temp <= 0)
                colour = Color.argb(255, randomColour.nextInt(COLOR_LIMIT), randomColour.nextInt(COLOR_LIMIT), randomColour.nextInt(COLOR_LIMIT));
            else
                colour = Color.argb(255, randomColour.nextInt(temp), randomColour.nextInt(temp), randomColour.nextInt(temp));

            temp-=colourGap;
        }

With the above code, i realize the color generated is more unique compared to the basic random. However, my code above is not flexible and just a temporary fix (i need to play with the iteration size and gap variable every time). I believe there should be any clever way to do this. Basically, i just keep decreasing the limit by 60 and if the limit is lesser or equal to 0 then i just generate a basic random color.

Any help is appreciated, and sorry English is not my mother language.

Thanks very much.

Blaze Tama
  • 10,828
  • 13
  • 69
  • 129

2 Answers2

4

You need to think of the "colour space" as a 3 dimensional space and look at the distance between your selected space in that.

i.e. the distance between r1,g1,b1 and r2,g2,b2 is sqrt((r1-r2)^2+(g1-g2)^2+(b1-b2)^2)

You can then check how close things are together and define a threshold.

A much easier way though will be just to define a "grid" of acceptable colours spaced far enough way from each other to look different.

i.e. r = random.nextInt(4)*32, g = random.nextInt(4)*32, b = random.nextInt(4)*32

Now you just have to check that none of your other generated colors exactly matches and you know there is a minimum distance between the selected. To guarantee a bit more distance you could check if any 2 or any 1 components exactly match although by doing that you reduce your number of possible colours massively.

Tim B
  • 40,716
  • 16
  • 83
  • 128
  • Sorry for the late reply, i will try your easier solution. Thanks – Blaze Tama Aug 16 '14 at 05:58
  • Thanks for your help, now i solved my main problem. Just a little question...therandomColour.nextInt(4) + 1) * 64 and randomColour.nextInt(8) + 1) * 32 only has a little difference. Now i need to organize the "difficulty" so i want to start with very easy and differen color. Any idea? – Blaze Tama Aug 16 '14 at 06:24
  • @BlazeTama Space the grid further apart, or check if any 2 colours match rather than checking all three. or even check if any 1 colour match although that will only allow a small number of colours. (i.e. if red 0 has already been taken then allow no other red 0s. – Tim B Aug 16 '14 at 15:06
2

Possibly this question may give you a clue.

The accepted answer suggests to change the Hue value of HSV color scheme with some interval, while making other two parameters random. This is how it would look like in Android:

for (int i = 0; i < 360; i += 360 / colorsNumber) {
    // hsv[0] is Hue [0 .. 360) hsv[1] is Saturation [0...1] hsv[2] is Value [0...1]
    float[] hsv = new float[3];
    hsv[0] = i;
    hsv[1] = (float) Math.random(); // Some restrictions here?
    hsv[2] = (float) Math.random();

    colors[i] = Color.HSVToColor(hsv);
}
Community
  • 1
  • 1