LINUX.ORG.RU

А помогите с градиентом (нужно показать температуру цветом)


0

1

Здрасьте. Моя софтина считает температурное поле во времени. Есть блоки, у каждого блока есть теплофизические параметры. И у каждого блока температура меняется во времени. Я визуализирую температуру через цвет.

Пока что сделал линейный градиент вот таким способом:

QColor Block::colorFromTemperature() const
{
    /// Минимальная составляющая цвета
    static const int min_color = 0;
    /// Максимальная составляющая цвета
    static const int max_color = 255;
    /// Температура (по модулю), до которой "тянется" градиент
    static const qreal max_absolute_temperature = 25;
    /// Текущая температура блока
    const qreal temperature = m_soil_block.temperature();

    /// Составляющая цвета, отражающая температуру
    int tmp = max_color - qRound((max_color - min_color)
                                 * qAbs(temperature) / max_absolute_temperature);
    tmp = qBound(min_color, tmp, max_color);

    const bool temperature_is_positive = temperature > 0;
    return QColor(temperature_is_positive ? max_color : tmp,
                  tmp,
                  temperature_is_positive ? tmp : max_color);
}

Не нравится. Самые важные изменения температуры идут от -4 до +4: тут нужно визуально отличать блоки с разницей в 0.2 — 0.3 градуса (что не получается с таким градиентом). Но также нужно иметь возможно визуально различать температуры от -25 до +25: после (+/-)4 нужно визуально отличать блоки с разницей 1-2 градуса.

Каким градиентом вы бы такое визуализировали? Думается мне, можно использовать десятичный логарифм для получения tmp, а прочее не менять. Но, может быть, можно ввести второй параметр или даже третий, чтобы цвет шёл от синего через голубой к белому и от белого через розовый к красному?

Вот так это сейчас выглядит: раз, два, три, четыре (зелёное — это количество незамёрзшей воды для блоков, в которых происходит фазовый переход).

★★★★★

p.s.: на части картинок использован max_absolute_temperature = 5, поэтому наблюдается обратная ситуация, около нуля всё хорошо различимо, а после 5 градусов всё одинаково

Obey-Kun ★★★★★
() автор топика

Может для каждой значимой температуры задать свой главный тон, а потом делать преобразование HSV -> RGB?

pathfinder ★★★★
()

>Каким градиентом вы бы такое визуализировали?

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

можно использовать десятичный логарифм для получения tmp

Почему десятичный? Попробуй разные основания (е, 4, 8) для оценки максимального цветового контраста в диапазоне от -4 до +4.

quickquest ★★★★★
()

Попробуйте f(x)=sign(x)*log10(abs(x)+1.0) с нормировкой на количество цветов и симметричной цветовой шкалой.

EtherealPhantom
()

В матлабе были цветовые схемы, среди них одна годная для температуры - плавный переход между несколькими цветами.

Может быть, простая кусочно-линейная функция поможет? Отрезки взять соответственно до -4, от -4 до 4 и после 4.

amomymous ★★★
()

Чем ParaView не устроил?

bvvv
()
Ответ на: комментарий от quickquest

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

Я знаю, изотермы сделаю. Обязательно сделаю, они для геокриологов нужны. Но пока с либой для них не определился. Проблема в том, что у меня данные не обязательно по сетке. Вот тут писал об этом: http://www.linux.org.ru/forum/talks/6160716

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

Э... как бы просится заюзать mathgl??? Все что можно разумного сделать в плане визуализации 2D-3D там уже сделано, причем сделано хорошо - не нужно строить велосипед. Это довольно таки муторная задача, так что изучение mathgl гарантированно сэкономит кучу времени, тем более что там есть C/C++ API и через диск данные гонять не надо. У автора на сайте есть галерея примеров, выбираете подходящую картинку и вперед...

AIv ★★★★★
()

По палитре - можно выбрать многоцветную палитру, можно выбрать периодическую палитру тогда изотермы вылезут автоматически. Напр http://a-iv.ru/aivlib/doc/aivlib.pdf стр 35

AIv ★★★★★
()

Как насчёт YUV? Если обойти квадрат по периметру при максимальной яркости (V), получатся наиболее яркие и сочные оттенки из возможных, причём по цветам радуги (если начать обходить из верхнего левого угла против часовой). Матрица для перехода из YUV в RGB известна.

prischeyadro ★★★☆☆
()

Ну напиши нелинейный градиент, максимально меняющийся в интересующей тебя области.

чтобы цвет шёл от синего через голубой к белому и от белого через розовый к красному?

Никаких проблем при реализации этого возникнуть не должно.

aedeph
()
Ответ на: комментарий от AIv

А как там изолинии делать? Не нашёл примера.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от AIv

и да, блоки в цвет мне всё равно раскрашивать надо, не для визуализации, а для удобного задания температуры пользователем.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

Глянул сам и не нашел изолиний... но можно у автора спросить (он кстати тут тоже бывает;-))

А какие сложности с раскраской? Подбираете подходящую палитру и красите, картинку в форточку, координаты курсора пересчитываете в блок и т.д. - там же вроде все просто?

AIv ★★★★★
()
Ответ на: комментарий от Obey-Kun

Да проблема с дырками IMHO вообще стоит - если ручками делать трассировку, то просто фиксируете что промазали и красите черным (серым). Если по блокам шарится так еще проще... все вменяемые графопостроители дырки вполне нормально обрабатывают.

AIv ★★★★★
()
Ответ на: комментарий от Obey-Kun

Насколько мне помнится общение с автором, просто задаете данные на сетке (возможно неоднородной и дырявой) а дальше оно само все делает...

Хотя в Вашем случае может имеет смысл взять однородную не-дырявую сетку и дырку забить нулями или нанами. Все таки из самых общих соображений строить поверхности на основе контейнера с однородной предсказуемой структурой куда проще и быстрее. Я во всяком случае обычно делаю именно так;-)

AIv ★★★★★
()
Ответ на: комментарий от AIv

> Насколько мне помнится общение с автором, просто задаете данные на сетке (возможно неоднородной и дырявой) а дальше оно само все делает...

А у меня не сетка :(. Блоки могу соприкасаться как угодно.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от anonymous

MathGL точно имеет привязки к питону. Насчет явы не помню, но гляньте документацию, если нет обратитесь опять таки к автору - может сделает.

А так - что мешает прогнать данные через диск и дернуть тот же MathGL или gnuplot как отд процесс в т.ч. и на яве?;-)

AIv ★★★★★
()
Ответ на: комментарий от Obey-Kun

То есть речь идет об отображении цветом на поле температур каких то блоков? Наск опять таки помнится, можно накладывать картинки друг на друга. Каждый блок в этом случае м.б. вообще рисовать отдельно?

AIv ★★★★★
()
Ответ на: комментарий от AIv

То есть речь идет об отображении цветом на поле температур каких то блоков?

Нет, блоки рисовать не надо. Просто они могут расположены хаотично, не по сетке. Могут вот так вот:

 __ __ __ __ __
|__|__|__|__|__|
|__|__|__|__|__|
|__|__|__|__|__|
|__|__|__|__|__|

Тогда это сетка. А могут и как-нибудь так:

 __ __ __ ___ __
|  |__|  |___|  |
|__|  |__|___|  |
|__|  |__|_|_|__|
|__|__|  |______|
|__|__|__|___|__|

В итоге получаем кучу температур блоков. А строить надо из того предположения, что температура блока говорит о температуре в его центре.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

Ну я во втором примере четко вижу сетку (базовую), но у нее некоторые ячейки объединены в большие блоки. Если это и правда так, то так и надо рисовать - каждая ячейка базовой сетки имеет температуру соотв. блока (блок может состоять из неск ячеек)?

AIv ★★★★★
()
Ответ на: комментарий от Obey-Kun

Я не очень понимаю как Вы считаете, но как вариант - что тогда мешает ввести сетку и накидать на нее температуру в соотв с Вашим форматом данных?

У меня в голове просто как то два варианта - либо сетка (к-ю и рисуем), либо отедельные блоки, но тогда и рисовать надо поблочно. Ничего другого в голову не приходит увы, не хватает воображения;-(

AIv ★★★★★
()
Ответ на: комментарий от AIv

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

На выходе получаем температуры по точкам, где точки — центры блоков.

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

jabbera нет, пиши в мыло aivanov(злая собака)keldysh.ru

AIv ★★★★★
()
Ответ на: комментарий от Obey-Kun

Дырки в MathGL легко делаются заданием NAN величины точек. А вообще я бы посоветовал нелинейный градиент — что-то типа

gr.SetFunc("","","",«tanh(c)»);

abalakin ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.