Friday, August 31, 2012

Progressively distributed RGB colors.


    public int getColor(int index) {
        int[] p = getPattern(index,0);
        return getElement(p[0]) << 16 | getElement(p[1]) << 8 | getElement(p[2]);
    }
Fetching routine.

    public int getElement(int index) {
        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;
    }
    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.


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:
  
    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);
    }
    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).

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

No comments: