public int getColor(int index) {Fetching routine.
int[] p = getPattern(index,0);
return getElement(p[0]) << 16 | getElement(p[1]) << 8 | getElement(p[2]);
}
public int getElement(int index) {It turns out to make numbers that go 255, 0, 128, 192, 64, ... it's just counting upwards and then flipping the order of the bits to being a big endian things rather than a small endian order. Starting from -1 rather than zero.
int value = index - 1;
int v = 0;
for (int i = 0; i < 8; i++) {
v = v | (value & 1);
v <<= 1;
value >>= 1;
}
v>>=1;
return v & 0xFF;
}
The only thing left is to pattern these numbers progressively. So everything with 0, then all permutations with 1, then all permutations with 2, then all permutations with 3 ect. There's bound to be a more elegant way to this than the way I did it but:
Which then cycles through producing first black then, every color 256 bits from black (namely white), then all the colors patterns with these bits, then adding in 128 and all the color patterns with that in the mix. Etc. Calling it recursively because apparently I'm a balla (an inelegant one at that).
public int[] getPattern(int index, int n) {
int[] p = new int[3];
if (index - 1 < 0) {
Arrays.fill(p,n);
return p;
}
index -= 1;
for (int q = 0; q < 3; q++) {
if (index - n < 0) {
Arrays.fill(p,n);
p[q] = index;
return p;
}
index -= n;
}
for (int q = 0; q < 3; q++) {
if (index - (n*n) < 0) {
boolean d = true;
for (int m = 0; m < 3; m++) {
if (m == q) p[m] = n;
else if (d) {
d = false;
p[m] = index / n;
}
else {
p[m] = index % n;
}
}
return p;
}
index -= (n * n);
}
return getPattern(index,n+1);
}
It might be better to just normalize the values there and feed them into something like LAB skipping imaginary colors etc.
Update:
If you are going to use this code, for whatever reason:
see the improved getPattern routine.
http://godsnotwheregodsnot.blogspot.com/2012/09/color-distribution-sans-recursion.html