How to dynamically compute a list of colors?

孤者浪人 提交于 2019-12-28 18:08:15

问题


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 the size of the List can vary, we need to be able to compute such a List of colors.


回答1:


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




回答2:


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;
}



回答3:


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:

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.



来源:https://stackoverflow.com/questions/3403826/how-to-dynamically-compute-a-list-of-colors

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!