Java: Better color selection algorithm
I have an ArrayList<Double>
, the values of which are converted into slices of an Arc2D.Pie
graph based on size (ie, an array of {1d,1d,2d,4d}
would create a graph with four slices, two of which occupy an eighth of the graph each, one of which occupies a fourth, and one of which occupies a half; together, the slices would be arranged to form a full circle). Each of these slices is colored differently both to allow for easy mapping of slices to other indicators (names, etc.) and to avoid blandness.
My algorithm for selecting colors was initially quite simple:
public Color getColor(int index, int total) {
return Color.getHSBColor((float) index / (float) total, 1f, 1f);
}
However, while this works well with most colors (red and blue, to name a few), some, such as cyan (especially prominent as the second element in a set of two; eg, an array of {1d, 3d}
) are not easily viewable by the human eye, as they are too light.
I have since changed the algorithm to
return Color.getHSBColor((float) index / (float) total, 1f, 0.8f);
in an attempt to darken the colors; however, cyan is still hard to see, and lowering the brightness further makes the colors rather hard to distinguish.
Does anyone have a nice, preferably simple algorithm that will create a spectrum of colors that are all easily viewable? A good test would be to generate yellowish and cyanish colors and see if they are easily viewable on a white background.
Thanks!
WC
EDIT : I have now improved my algorithm to make more varied colors, by varying saturation and lightness. The colors look choppier, though; any more ideas?
New algorithm:
float hue = (float) seriesIndex / (float) totalSeries;
int steps = 4;
float saturation = ((seriesIndex) % steps / (2f * steps)) + (0.5f);
float brightness = ((seriesIndex + ((steps + 1) / 2f)) % (steps + 1f) / (2f * (steps + 1f))) + 0.5f;
Color c = Color.getHSBColor(hue, saturation, brightness);
I like greyscale
Color.rgb( 255 * (float)index/(float)total, 255 * (float)index/(float)total, 255 * (float)index/(float)total);
Otherwise, the field of color segmentation is pretty big. Some people are okay breaking it up into bands.
Otherwise, if you just need 4 colors, I would pick ones that work good and pick from a table: Such as Red, Blue, Green and Black.
The best algorithm I've found so far uses a previous SO algorithm that's I've modified. I keep MIX
at a constant light gray ( Color.LIGHT_GRAY
), and use a seeded Random
object so that the color is always the same for each iteration, but different between.
Random random = new Random(seriesIndex);
int red = random.nextInt(256);
int green = random.nextInt(256);
int blue = random.nextInt(256);
// mix the color
if (MIX != null) {
red = (red + MIX.getRed()) / 2;
green = (green + MIX.getGreen()) / 2;
blue = (blue + MIX.getBlue()) / 2;
}
Color c = new Color(red, green, blue);
It turns out with nice-looking colors that are fairly discernable.
Thanks to nmjohn for helping me solve this, giving me ideas, and pointing me in the right direction!
WC
NOTE : I'll leave this open for two days. If anyone comes up with a nicer algorithm, I'll accept his. Otherwise, I'll accept this.
链接地址: http://www.djcxy.com/p/87078.html上一篇: Android 4.0上Holo主题的默认颜色值是什么?
下一篇: Java:更好的颜色选择算法