2016-11-16 4 views
1

то, что я пытаюсь сделать, это заполнить массив градиентом радуги. Массив должен содержать 256 записей, заполненных шестнадцатеричным значением цветов.Fill массив динамически с градиентом цвета C++

rainbow

как:

array[0] = 0xFF0000 //red 
... 
array[85] = 0xFFA200 //orange 
... 
array[170] = 0x00AF0F //green 
... 
array[255] = 0xAE00FF //purple 

, потому что я не хочу, чтобы назначить все 256 цветов «вручную» на массив, я ищу для подхода к динамично, что. Не обязательно, чтобы это был ракурс, показанный выше. Картина предназначена только для демонстрации.

Любые предложения, как это сделать в (предпочтительно) сокращении короткого кода, избегая пары вложенных циклов?

+0

_ «Это не обязательно должно быть радуга, отображаемая выше». Итак, случайные 256 значений? – P0W

+1

@ P0W больше похоже на радугу, но не на то, что я бы предположил. – Borgleader

+3

Подсказка: значения Hex могут показаться сложными для изменения, но на самом деле каждый цвет представляет собой комбинацию из трех целых чисел (R, G, B). – SingerOfTheFall

ответ

1

Вы хотите перейти от красного до желтого
Next, желтого до зеленого
Далее, зеленого до светло-голубого
Далее, светло-голубого до темно-синего
Далее, темно-синего до фиолетового
и обратно в красный ,

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

255,0,0 -> 255,255,0 -> 0,255,0 -> 0,255,255 -> 0,0,255 -> 255,0,255 -> 255,0,0 

Это можно сделать с помощью следующего кода, где диапазон оттенков составляет от 0.0f до 1.0f

unsigned int rgb(double hue) 
{ 
    int h = int(hue * 256 * 6); 
    int x = h % 0x100; 

    int r = 0, g = 0, b = 0; 
    switch (h/256) 
    { 
    case 0: r = 255; g = x;  break; 
    case 1: g = 255; r = 255 - x; break; 
    case 2: g = 255; b = x;  break; 
    case 3: b = 255; g = 255 - x; break; 
    case 4: b = 255; r = x;  break; 
    case 5: r = 255; b = 255 - x; break; 
    } 

    return r + (g << 8) + (b << 16); 
} 

Использование:

double range = 500; 
for (double i = 0; i < range; i++) 
{ 
    unsigned int color = rgb(i/range); 
    ... 
} 

Выход:

enter image description here

+0

отлично! именно то, что я искал! Теперь генерация цвета rgb имеет для меня даже смысл. прекрасный – user1234

1

Один из способов сделать то, что вы хотите, - это интерполировать каждый из цветов компонентов (RGB) от их начала до конечного значения. Это означает использование шагов, которые имеют равный размер, насколько это возможно.

Для получения компонентов RGB необходимо немного манипулировать. Этот код дает вам три компонента цвета для полностью указанного цвета fullColour:

std::array<float, 3> colourRGB; 

for(unsigned i = 0; i<3; ++i) { 
    colourRGB[i] = (fullColour & (0xFF << (i*8))) >> (i*8); 

Вы используете это, чтобы получить массив RGB вашего начального и конечного цвета (например, для красно-оранжевого диапазона в вашем примере это будет RGB пробой 0xFF0000 и 0xFFA200). Для каждого компонента вы затем определяете размер шага, необходимый для каждого шага в вашем «затухании». Это определяется общим изменением этого компонента, деленным на общее количество шагов. Для красно-оранжевого примера размер шага для компонента Red будет таким образом 1,91 (потому что у вас есть 86 шагов и общее изменение (0xA2 - 0x00 или 162 в десятичной форме, что дает 162/86 = 1,91). Размеры шага для остальные компоненты равны нулю, так как они не меняются.

Затем вы можете выполнить итерацию по шагам, добавив еще один размер шага и округление, чтобы получить новое значение для каждого компонента. Например, на этапе s:

red[s] = startingRed + ((float)s * stepSizeRed) 

Чтобы повторно объединить значения RGB обратно в полном цвете, просто применить некоторые манипуляции с битами снова:

fullColour[s] = 0; 
for(unsigned i=0; i<3; ++i) 
    fullColour[s] += rgbComponent[s][i] << (i*8); 

Этот подход дает требуемое «затухание» от любого начала до любого конечного цвета на любом количестве шагов.

+0

спасибо за это, но ваш код грубо трудно понять, из-за того, что я не уверен, что, например, 'red [s]' или 'startRed' is is is' 'colourRGB' то же самое, что' fullColour' и т. д.? Было бы здорово, если бы вы могли приложить «полный»/«рабочий» пример красно-оранжевого образца, который вы предоставили. ура – user1234

 Смежные вопросы

  • Нет связанных вопросов^_^