МОДЕЛЬ ЦВЕТА HSV
В интерфейсах выбора цвета часто используется модель цвета, основанная на интуитивных концепциях, а не на наборе основных цветов. Отметим, что спецификацию цвета в интуитивной модели можно дать, выбирая спектральный цвет и долю белого и черного, которую нужно добавить к этому цвету, чтобы получить различные тени, оттенки и тона (раздел 12.2).
ПРЕОБРАЗОВАНИЯ МЕЖДУ ПРОСТРАНСТВАМИ ЦВЕТОВ HSV И RGB
Чтобы определить операции, требуемые для перехода между пространствами HSV и RGB, рассмотрим вначале, как конус HSV можно построить из куба RGB. Диагональ RGB-куба, идущая от черного (начало координат) к белому, соответствует оси V конуса. Кроме того, каждый подкуб куба RGB соответствует шестиугольному сечению конуса. На любом сечении все стороны шестиугольника и все радиальные линии от оси V к любой вершине имеют постоянное значение V. Следовательно, для любого набора значений RGB V равно значению максимального компонента RGB. Точка HSV, соответствующая этому набору значений RGB, лежит на шестиугольном сечении, характеризуемом значением V. Далее определяется параметр 5' - относительное расстояние от этой точки до оси V. Параметр Н вычисляется как относительное положение точки в каждом секстанте шестиугольника. Алгоритм отображения любого набора 1ЮВ-значений в соответствующие ЖУ-значения реализован в приведенной ниже процедуре.
class rgbSpace {public: float r, g, b;}; class hsvSpace {public: float h, s, v;}; const float noHue = -1.0;
inline float min(float a, float b) {return (a < b)? a : b;} inline float max(float a, float b) {return (a > b)? a : b;}
void rgbTOhsv (rgbSpaceS rgb, hsvSpace& hsv)
{
/* Значения RGB и HSV принадлежат диапазону 0-1,0 */ float minRGB = min (r, min (g, b)), maxRGB = max (r, max (g, b)); float deltaRGB = maxRGB - minRGB;
v = maxRGB; if (maxRGB != 0.0)
s = deltaRGB / maxRGB; else
s = 0.0; if (s <= 0.0) h = noHue; else {
if (r == maxRGB)
h = (g - b) / deltaRGB; else
if (g == maxRGB)
h=2.0+ (b-r) / deltaRGB; else
if (b == maxRGB)
h=4.0+ (r-g) / deltaRGB; h *= 60.0; if (h < 0.0) h += 360.0; h /= 360.0;
}
}
Преобразование из пространства HSV в пространство RGB определяется обратными операциями, которые выполняются для каждого секстанта конуса. Окончательные уравнения преобразования сведены в представленном ниже алгоритме.
class rgbSpace {public: float r, g, b;}; class hsvSpace {public: float h, s, v;}; void hsvTOrgb (hsvSpaceS hsv, rgbSpaceS rgb)
{
/* Значения HSV и RGB принадлежат диапазону 0-1,0 */ int к
float aa, bb, cc, f; if ( s <= 0.0)
r=g=b=v; // Если s = 0, получаем шкалу полутонов, else {
if (h == 1.0) h = 0.0; h *= 6.0; k = floor (h); f = h - k; aa = v * (1 *. 0 - s);
bb = v * (1.0 - (s * f));
cc = v * (1.0 - (s * (1.0 - f)));