How to dynamically compute a list of colors?

前端 未结 3 1064
粉色の甜心
粉色の甜心 2020-12-10 18:19

In order to represent a List of Objects with different colors in a GWT-Widget, we need to get dynamically a List of colors with as much different colors as objects. Since th

相关标签:
3条回答
  • 2020-12-10 18:58

    Another version of my solution with ranges:

    List<int> getUniqueColors(int amount) {
        final int lowerLimit = 0x10;
        final int upperLimit = 0xE0;    
        final int colorStep = (upperLimit-lowerLimit)/Math.pow(amount,1f/3);
    
        final List<int> colors = new ArrayList<int>(amount);
    
        for (int R = lowerLimit;R < upperLimit; R+=colorStep)
            for (int G = lowerLimit;G < upperLimit; G+=colorStep)
                for (int B = lowerLimit;B < upperLimit; B+=colorStep) {
                    if (colors.size() >= amount) { //The calculated step is not very precise, so this safeguard is appropriate
                        return colors;
                    } else {
                        int color = (R<<16)+(G<<8)+(B);
                        colors.add(color);
                    }               
                }
        return colors;
    }
    

    This one is more advance as it generates the colors that differ from each other as much as possible (something like @aiiobe did).

    Generally we split the range to 3 subranges of red green and blue, calculate how many steps do we need to iterate each of them (by applying a pow(range,1f/3)) and iterate them.

    Given the number 3 for example, it will generate 0x0000B1, 0x00B100, 0x00B1B1. For number 10 it will be: 0x000076, 0x0000EC, 0x007600, 0x007676, 0x0076EC, 0x00EC00, 0x00EC76, 0x00ECEC, 0x760000, 0x760076

    0 讨论(0)
  • 2020-12-10 19:01

    Something like this would do I guess. No randomness, just calculates which color steps to take and splits all color range to that steps. If you limit the lower limit - you will remove too dark colors, and limiting the upper limit will remove too bright colors.

    List<Integer> getUniqueColors(int amount) {
        final int lowerLimit = 0x101010;
        final int upperLimit = 0xE0E0E0;
        final int colorStep = (upperLimit-lowerLimit)/amount;
    
        final List<Integer> colors = new ArrayList<Integer>(amount);
        for (int i=0;i<amount;i++) {
            int color = lowerLimit+colorStep*i;
            colors.add(color);
        }
        return colors;
    }
    
    0 讨论(0)
  • 2020-12-10 19:14

    If I understand your situation correct, you're after a number of colors that look sort of "as different as possible"? I would in that case suggest that you vary the hue value (two red colors with slightly different brightness won't look much different), so you get something like a "rainbow-palette":

    This can be achieved with the following code:

    Color[] cols = new Color[n];
    for (int i = 0; i < n; i++)
        cols[i] = Color.getHSBColor((float) i / n, 1, 1);
    

    An example usage with a screen shots below:

    import java.awt.*;
    
    public class TestComponent extends JPanel {
    
        int numCols = 6;
    
        public void paint(Graphics g) {
    
            float h = 0, dh = (float) getHeight() / numCols;
            Color[] cols = getDifferentColors(numCols);
    
            for (int i = 0; i < numCols; i++) {
                g.setColor(cols[i]);
                g.fillRect(0, (int) h, getWidth(), (int) (h += dh));
            }
        }
    
        public static Color[] getDifferentColors(int n) {
            Color[] cols = new Color[n];
            for (int i = 0; i < n; i++)
                cols[i] = Color.getHSBColor((float) i / n, 1, 1);
            return cols;
        }
    
        public static void main(String s[]) {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(new TestComponent());
            f.setSize(200, 200);
            f.setVisible(true);
        }
    }
    

    numCols = 6 and numCols = 40 yields the following two screenshots:

    enter image description here enter image description here

    If you need like more than 30 colors, you could of course change the brightness and perhaps the saturation as well, and have, for instance, 10 dark colors, 10 midtone colors, and 10 bright colors.

    0 讨论(0)
提交回复
热议问题