Страница 1 из 2
Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
05.03.2012 (Пн) 18:01
jangle
Есть круговая диаграмма, в которой возможно 10-20 элементов, как раскрасить ее так, чтобы не было совпадение цветов у ближайших элементов? И они были максимально контрастными по отношению к соседям.
Сейчас распределяю цвета рандомно, что совсем неправильно, иногда цвет легенды у разных элементов совпадает. Нужен какой-то алгоритм, чтобы создаваемые цвета были максимально контрастными по отношению к соседям.
Re: Распределение окраски на круговой диаграмме
Добавлено:
05.03.2012 (Пн) 19:28
Alec
А если задавать тон в цветовой модели HSV? Например, для 10 элементов задаем тоны 0, 0.1, 0.2 и т.д., а выводим в последовательности 0, 0.5, 0.2, 0.7 и т.д.
Re: Распределение окраски на круговой диаграмме
Добавлено:
05.03.2012 (Пн) 20:04
alibek
20 цветов можно просто таблицей задать.
Добавлено:
05.03.2012 (Пн) 20:07
Qwertiy
Вариант 1: Заранее подобрать цвета.
Вариант 2: Рассматривая цвет как Long брать I * (&H01000000 \ ColrorCount), где ColorCount - некоторая заранее подобранная константа. Насколько я помню, можно выбрать что-то типа типа 1023, 31, 17 (может поподбирать придётся).
Re: Распределение окраски на круговой диаграмме
Добавлено:
05.03.2012 (Пн) 22:14
Sam777e
alibek писал(а):20 цветов можно просто таблицей задать.
+1
Re: Распределение окраски на круговой диаграмме
Добавлено:
05.03.2012 (Пн) 22:17
jangle
alibek писал(а):20 цветов можно просто таблицей задать.
Пока 20 разделов, в последствии их может быть больше. В принципе это количество не ограниченно.
Re: Распределение окраски на круговой диаграмме
Добавлено:
06.03.2012 (Вт) 5:53
Хакер
Берёшь любую радугу, которая достаточно плавная, и у которой один конец предельно близок к другому, например как здесь:
- rainbow_wnd.png (6.47 Кб) Просмотров: 15932
Берём полоску с радугой:
- rainbow_bar.png (485 байт) Просмотров: 15932
Склеиваем края этой полоски, так, чтобы получилось кольцо:
Если вывернуть изначальный пример, получается что-то такое:
- warped_ring_sample.png (20.22 Кб) Просмотров: 15932
У такой окружности есть важное свойство: любой проведённый диаметр соединят пару точек с противоположенными цветами, а любые две равные хорды, проведённые две точки — пару точек «равноудалённых» по оттенку от заданной.
Теперь к делу: нам нужно выбрать цвета для N-секторной диаграммы. Для примера: нам нужно выбрать цвета для 5-секторной диаграммы.
Мы просто строим пятиконечную звезду внутри нашего кольца:
- penta_ring.png (32.07 Кб) Просмотров: 15932
Всё, 5 цветов есть. Цвета нужно брать в направлении обхода звезды, то есть: красный→зелёный→фиолетовый→лайм→лазурный.
Способов построени N-угольников (включая самопересекающиеся) существуют целые семейства:
Нужно брать зелёные звёзды — это т.н. связные звёзды.
Разумеется, что в реальности ничего не нужно строить: кольцо расчитывается математический, координаты точек расчитываются математически.
В итоге получение цвета — чисто по формуле.
Пример:
Re: Распределение окраски на круговой диаграмме
Добавлено:
06.03.2012 (Вт) 8:48
alibek
jangle писал(а):Пока 20 разделов, в последствии их может быть больше. В принципе это количество не ограниченно.
Тогда по HSV-модели, как советовали в первом ответе. Только в этом уже мало смысла, цвета будут сливаться и глаз будет их путать.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 8:57
Хакер
Если идти по звезде, то сливаться не будут, наоборот, будут пестрить.
Другое дело, что легенду, основанную на сопоставлении цветов легенды с цветами секторов — уже не сделать.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 9:23
alibek
Хакер писал(а):Если идти по звезде, то сливаться не будут, наоборот, будут пестрить.
Другое дело, что легенду, основанную на сопоставлении цветов легенды с цветами секторов — уже не сделать.
Я имел ввиду под "сливаться" именно это, глаз не сможет однозначно определить соответствие цвета легенде.
Если идти не по звезде, а просто по HSV-окружности с определенным шагом (n/1 в твоей диаграмме), тогда сопоставлять цвета легенде будет проще, но тогда наглядность пострадает.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 9:50
jangle
Берёшь любую радугу, которая достаточно плавная, и у которой один конец предельно близок к другому, например как здесь:
Хакер спасибо! Очень интересный алгоритм, буду пробовать его реализовать.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 9:51
Хакер
Я реализовал, но исходник утрачен — пропало напряжение на полсекунды.
Там строк 80 кода.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 10:22
Proxy
Alec писал(а):А если задавать тон в цветовой модели HSV? Например, для 10 элементов задаем тоны 0, 0.1, 0.2 и т.д., а выводим в последовательности 0, 0.5, 0.2, 0.7 и т.д.
Хакер писал(а):Разумеется, что в реальности ничего не нужно строить: кольцо расчитывается математический, координаты точек расчитываются математически.
2 идентичных варианта, в первом лишь шаг неудачный (помимо шага в варианте Хакера всё аналогично, тоже работа с тоном (Hue), значит помимо шага сам математически "круг" выразить очень просто из системы уравнений HSV -> RGB).
И я вижу недочёт при большом количестве секторов: если у кого-то возникнет желание сопоставить сектора с легендой, то он сядет на сопоставлении оттенков синего (физиология, оттенки синего человек различает хуже всего). ИМХО можно заведомо выбирать на несколько процентов больше цветов, а затем отбрасывать слишком близко расположенные оттенки синего. При таком шаге это не скажется на различимости двух соседних секторов. Так можно будет сохранить читаемость при большей плотности (выноски едва ли помогут, они вообще перекроются, если сектора будут маленькими и их придётся при перекрытии вообще скрывать).
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 10:26
Хакер
Мой вариант предполагает в частности выбор произвольной радуги. То есть необязательно прогон Hue от 0° до 360°, хотя лично я реализовывал именно этот вариант. Но радугу можно выбирать такой, что разные оттенки будут иметь разные SB-составляющие, плюс можно сделать немонотонный dH/dx.
Ну и плюс шаг выбирается не от-балды, а по закономерности (причём вариантов закономерности — вон сколько).
Но вообще да, идея та же, не спорю.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 10:31
Proxy
Хакер писал(а):Ну и плюс шаг выбирается не от-балды, а по закономерности (причём вариантов закономерности — вон сколько).
А где я сказал про шаг от балды?
Шаг лучше и не придумать.
Хакер писал(а):Мой вариант предполагает в частности выбор произвольной радуги.
Не знал. В любом случае с составлением "умной" радуги + шагом по звезде будет не проще, чем с использованием готовой радуги Hue из HSV (при прочих константах), шага по звезде, а затем отбросом лишних цветов. А лучше было бы и вовсе добавить зависимость смещения от целевого угла и красиво и равномерно "разуплотнить" кольцо к Юго-Западу.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 11:41
alibek
Proxy писал(а):В любом случае с составлением "умной" радуги + шагом по звезде будет не проще, чем с использованием готовой радуги Hue из HSV (при прочих константах), шага по звезде, а затем отбросом лишних цветов.
Это по сути одно и то же. Просто
Хакер визуализировал алгоритм выбора оптимального шага.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 13:58
Proxy
Извиняюсь заранее за оффтоп, но как тут найти угол между вершиной A звезды, центром описанной окружности и вершиной B, смежной с вершиной A? Ака выше "шаг".
Хакер писал(а):Там строк 80 кода.
Полагаю поиск этого угла занял порядка 40 строк?
UPD. Кажется придумал
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 14:01
Хакер
На картинке написано. {m/n}
n — кол-во вершин.
m — константа, определяющая способ построение.
Дробь {m/n} определяет, на сколько частей делить окружность. Иначе говоря: 360 / (m/n) = угол.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 14:12
Proxy
Без разуплотнения синего:
Печатает 5, а затем 8 цифр разных цветов с "шагом" "по звезде"
- Код: Выделить всё
Option Explicit
Private Sub Form_Load()
AutoRedraw = True
PrintCols 5
PrintCols 8
End Sub
Private Sub PrintCols(totalCols As Long) 'печатает цифры уникальных цветов
Dim i As Long
Dim lastCornerAngle As Single
Dim AngleStep As Single
lastCornerAngle = 0
AngleStep = 180 - IIf(totalCols Mod 2 = 0, 1, 0.5) * (360 / totalCols)
For i = 1 To totalCols
lastCornerAngle = lastCornerAngle + AngleStep
Form1.ForeColor = HSV2RGBeasy(lastCornerAngle, 1, 1)
Print i
Next
End Sub
Private Function HSV2RGBeasy(Hue As Single, Saturation As Single, ValueBr As Single) As Long 'просто получает RGB из HSV
Dim f As Single, p As Single, q As Single, t As Single
f = (Hue / 60) - (Hue \ 60)
p = (ValueBr * (1 - Saturation)) * 255
q = (ValueBr * (1 - f * Saturation)) * 255
t = (ValueBr * (1 - (1 - f) * Saturation)) * 255
f = f * 255: ValueBr = ValueBr * 255
Select Case ((Hue \ 60) Mod 6)
Case 0
HSV2RGBeasy = RGB(ValueBr, t, p)
Case 1
HSV2RGBeasy = RGB(q, ValueBr, p)
Case 2
HSV2RGBeasy = RGB(p, ValueBr, t)
Case 3
HSV2RGBeasy = RGB(p, q, ValueBr)
Case 4
HSV2RGBeasy = RGB(t, p, ValueBr)
Case 5
HSV2RGBeasy = RGB(ValueBr, p, q)
End Select
End Function
Можно просто вместо печати циферок помещать в массив цвета, чтобы потом использовать. Число уникальных цветов назначается через параметр процедуры PrintCols
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 14:54
Хакер
Нда.
Стоило ли писать гигантскую функцию HSV2RGBeasy, принимающую 3 параметра, чтобы потом при вызове в качестве двух последних всегда указывать 1 и 1?
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 16:19
Proxy
Хакер писал(а):Нда.
Стоило ли писать гигантскую функцию HSV2RGBeasy, принимающую 3 параметра, чтобы потом при вызове в качестве двух последних всегда указывать 1 и 1?
На перспективу, может насыщенность иная потребуется или ещё что.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 18:29
Mikle
Можно представить диапазон доступных цветов, как RGB куб, точнее параллелепипед, коэффициенты "заметности" RGB компонентов давно известны: R=77, G=150, B=28. Делаем параллелепипед с такими сторонами, первый цвет берём случайный, каждый следующий - точка, максимально удалённая от уже занятых.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 19:18
Proxy
Mikle писал(а):первый цвет берём случайный, каждый следующий - точка, максимально удалённая от уже занятых.
В такой формулировке первой точкой будет произвольная, второй вершина, третей противоположная вершина, четвёртой опять первая вершина и т.д. Или же я что-то неправильно понял.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
06.03.2012 (Вт) 19:24
Mikle
Вторая-третья - точно вершины, а дальше - зависит от первой точки.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
07.03.2012 (Ср) 12:31
Antonariy
jangle писал(а):Берёшь любую радугу, которая достаточно плавная, и у которой один конец предельно близок к другому, например как здесь:
Хакер спасибо! Очень интересный алгоритм, буду пробовать его реализовать.
Дальтоники в пролете с этим алгоритмом.
Наверно поэтому в MS цветовые схемы для винды создают вручную.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
07.03.2012 (Ср) 12:33
Хакер
Дальтоники в пролёте с любым алгоритмом, если у них расстройство восприятие такое, что цветов нет вообще.
Если же расстройство такое, что есть частичное нарушение восприятия, то это решается подбором соответствующей радуги.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
07.03.2012 (Ср) 12:44
Antonariy
Значит нужно предоставить на выбор несколько радуг. Или как-то ее параметризировать. Даже человеку с нормальным зрением может выпасть неудобная комбинация.
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
07.03.2012 (Ср) 13:10
Хакер
Пример с человеком с нормальным зрением и неудачной комбинацией, выбранной по «звёздному» методу?
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
07.03.2012 (Ср) 13:59
Proxy
Antonariy писал(а):Значит нужно предоставить на выбор несколько радуг. Или как-то ее параметризировать. Даже человеку с нормальным зрением может выпасть неудобная комбинация.
Antonariy писал(а):Дальтоники в пролете с этим алгоритмом.
48 элементов. Звезда работает как надо. Единственное чуть-чуть увеличить угол между оттенками синего (всего 1 функция потребуется, у которой параметром оригинальный угол, а выводит скорректированный), а в плане дальтонизма едва ли лучше может получиться при таком количестве элементов. Можно для них по контрасту добавить коррекцию, чтобы вся "гамма" серого использовалась (впрочем даже попробую...).
Re: Алгоритм подбора цветов секторов круговой диаграммы
Добавлено:
07.03.2012 (Ср) 14:14
Antonariy
Хакер писал(а):Пример с человеком с нормальным зрением и неудачной комбинацией, выбранной по «звёздному» методу?
Мне не нравится 19-23 и 43-45 со скриншота Proxy. Но в целом результат достойный.