Нужна помощь в понимании алгоритма цветового отображения - PullRequest
0 голосов
/ 27 февраля 2019

Итак, я работаю над проектом, который включает в себя создание уже существующего скелетного кода приложения, имитирующего «поток жидкости и визуализацию», и применение к нему различных методов визуализации.

Первый шаг проектазаключается в применении различных методов цветового отображения к трем различным наборам данных, а именно: плотность жидкости (rho), величина скорости жидкости (|| v ||) и величина силового поля || f ||.

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

Фрагмент кода, который я пытаюсь понять, следующий:

//rainbow: Implements a color palette, mapping the scalar 'value' to a rainbow color RGB
    void rainbow(float value,float* R,float* G,float* B)
    {                          
       const float dx=0.8; 
       if (value<0) value=0; if (value>1) value=1;
       value = (6-2*dx)*value+dx;
       *R = max(0.0,(3-fabs(value-4)-fabs(value-5))/2);
       *G = max(0.0,(4-fabs(value-2)-fabs(value-4))/2);
       *B = max(0.0,(3-fabs(value-1)-fabs(value-2))/2);
    }

float value, передаваемый первым параметром, насколько я могу судить, это плотность жидкости.Я определил это, изучив эти два фрагмента.

//set_colormap: Sets three different types of colormaps
void set_colormap(float vy)
{
   float R,G,B; 

   if (scalar_col==COLOR_BLACKWHITE)
       R = G = B = vy;
   else if (scalar_col==COLOR_RAINBOW)
       rainbow(vy,&R,&G,&B); 
   else if (scalar_col==COLOR_BANDS)
       {  
          const int NLEVELS = 7;
          vy *= NLEVELS; vy = (int)(vy); vy/= NLEVELS; 
          rainbow(vy,&R,&G,&B);   
       }

   glColor3f(R,G,B);
}

и

set_colormap(rho[idx0]);
glVertex2f(px0, py0);
set_colormap(rho[idx1]);
glVertex2f(px1, py1);
set_colormap(rho[idx2]);
glVertex2f(px2, py2);


set_colormap(rho[idx0]);
glVertex2f(px0, py0);
set_colormap(rho[idx2]);
glVertex2f(px2, py2);
set_colormap(rho[idx3]);
glVertex2f(px3, py3);

С учетом всего сказанного, может кто-нибудь объяснить мне, как работает первый метод?

Вот вывод, когда метод вызывается пользователем и материя вводится в окно с помощью курсора:

-

Тогда как в противном случае это выглядело бы так (в оттенках серого):

-

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Я не уверен, какую часть функции вы не понимаете, поэтому позвольте мне объяснить эту строку построчно:

void rainbow(float value,float* R,float* G,float* B){

}

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

const float dx=0.8;

Затем инициализируется постоянная dx.Я не уверен, что означает название «dx», но похоже, что оно позже используется для определения того, какая часть цветового спектра используется.

if (value<0) value=0; if (value>1) value=1;

Это ограничивает входные данные значением от 0 до1.

   value = (6-2*dx)*value+dx;

Это отображает входные данные в значение между dx и 6-dx.

   *R = max(0.0,(3-fabs(value-4)-fabs(value-5))/2);

Это, вероятно, самая сложная часть.Если value меньше 4, это упрощается до max(0.0,(2*value-6)/2) или max(0.0,value-3).Это означает, что если value меньше 3, красный вывод будет равен 0, а если он находится между 3 и 4, то будет value-3.

Если value находится между 4 и 5вместо этого эта строка упрощается до max(0.0,(3-(value-4)-(5-value))/2), что равно 1. Поэтому, если value находится между 4 и 5, красный вывод будет равен 1.

Наконец, если value больше 5,эта строка упрощается до max(0.0,(12-2*value)/2) или просто 6-value.

Таким образом, вывод R равен 1, когда value находится между 4 и 5, 0, когда value меньше 3, и что-то вмежду прочим.Расчеты для зеленого и синего выходных данных или почти одинаковые, только с измененной величинойзеленый - самый яркий для значений от 2 до 4, а синий - самый яркий для значений от 1 до 2. Таким образом, выходной сигнал формирует плавный спектр цветов радуги.

0 голосов
/ 27 февраля 2019

Я подозреваю, что это изменение от HSV до RGB .

Идея состоит в том, что вы можете сопоставить свою плотность жидкости (в линейном масштабе) с параметром оттенка цветав формате HSV .Насыщенность и значение могут просто поддерживать постоянное значение 1. Обычно оттенок начинается и заканчивается красным, поэтому вы также хотите сместить значения оттенка в диапазон [красный, синий].Это даст вам «тепловую карту» цветов в формате HSV в зависимости от плотности жидкости, которую затем необходимо отобразить в RGB в шейдере.

Поскольку некоторые из ваших значений можно поддерживать постоянными, а потому что вы неНе заботясь о каких-либо промежуточных результатах, алгоритм, который преобразует плотность жидкости в RGB, можно упростить до приведенного выше фрагмента.

...