Java: лучший алгоритм выбора цвета - PullRequest
2 голосов
/ 09 января 2012

У меня есть ArrayList<Double>, значения которого преобразуются в срезы графа Arc2D.Pie на основе размера (т. Е. Массив {1d,1d,2d,4d} создаст граф с четырьмя срезами, два из которых занимают восьмуюкаждого графика, один из которых занимает четвертый, а другой - половину; вместе срезы будут расположены так, чтобы образовать полный круг).Каждый из этих срезов окрашен по-разному, что позволяет легко сопоставлять срезы с другими индикаторами (именами и т. Д.) И избегать мягкости.

Мой алгоритм выбора цветов изначально был довольно прост:

public Color getColor(int index, int total) {
    return Color.getHSBColor((float) index / (float) total, 1f, 1f);
}

Тем не менее, хотя это хорошо работает с большинством цветов (красный и синий, чтобы назвать несколько), некоторые, такие как голубой (особенно заметный как второй элемент в наборе из двух, например, массив {1d, 3d}) человеческий глаз не так легко увидеть, так как он слишком светлый.

С тех пор я изменил алгоритм на

return Color.getHSBColor((float) index / (float) total, 1f, 0.8f);

, пытаясь затемнить цвета;однако, голубой цвет по-прежнему трудно увидеть, а снижение яркости еще больше затрудняет его различение.

Есть ли у кого-нибудь хороший, желательно простой алгоритм, который создаст спектр цветов, которые все легко просматривать?Хорошим тестом будет создание желтоватых и голубых цветов и проверка, легко ли их можно увидеть на белом фоне.

Спасибо!

WC

EDIT : Теперь я улучшил свой алгоритм для создания более разнообразных цветов, меняя насыщенность и яркость.Тем не менее, цвета выглядят более мягкими;Есть еще идеи?

Новый алгоритм:

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

Ответы [ 2 ]

1 голос
/ 09 января 2012

Лучший алгоритм, который я нашел, использует предыдущий алгоритм SO , который я модифицировал.Я держу MIX на постоянном светло-сером (Color.LIGHT_GRAY) и использую засеянный объект Random, чтобы цвет всегда был одинаковым для каждой итерации, но различался между.

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

Этополучается с красивыми цветами, которые довольно различимы.

Example image

Спасибо nmjohn за помощь в решении этой проблемы, предоставление идей и указание на меняправильное направление!

WC

ПРИМЕЧАНИЕ : я оставлю это открытым на два дня.Если кто-нибудь придумает более хороший алгоритм, я приму его.В противном случае я приму это.

1 голос
/ 09 января 2012

Мне нравится оттенки серого

 Color.rgb( 255 * (float)index/(float)total, 255 * (float)index/(float)total, 255 *      (float)index/(float)total);

В противном случае поле цветовой сегментации довольно велико. Некоторые люди хорошо разбивают его на группы.

В противном случае, если вам просто нужно 4 цвета, я бы выбрал те, которые хорошо работают, и выбрал бы из таблицы: красный, синий, зеленый и черный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...