From: Colm Buckley (colm at domain tuatha.org)
Date: Fri 03 Sep 1999 - 11:39:48 IST
> They have a rectangular spectrum of colours, and as you click/slide
> around it, the RGB and hue/lum/sat values vary.
In the picker you show in the picture, the horizontal axis of the square
is Hue and the vertical is Saturation. The slider to the right of the
square is Value.
Hue isn't normally shown as a straight axis on a square; as it "wraps
around", it's more usually shown as an angle [0..360) degrees around a
disc (with radius given by Saturation).
Here's C++ code To convert from RGB to HSV and back - it needs "math.h"
const double UNDEFINED = -10000;
/*
* Convert RGB space to HSV space
*
* Inputs : r, g, b in the range [0,1]
* Outputs : h in the range [0,360) or UNDEFINED
* s, v in the range [0,1]
*/
void rgb_to_hsv(double r, double g, double b, double &h, double &s, double &v)
{
/* clip to the required range */
r = (r > 1.0) ? 1.0 : ((r < 0.0) ? 0.0 : r);
g = (g > 1.0) ? 1.0 : ((g < 0.0) ? 0.0 : g);
b = (b > 1.0) ? 1.0 : ((b < 0.0) ? 0.0 : b);
double max = r, min = r;
if (g > max) max = g; if (g < min) min = g;
if (b > max) max = b; if (b < min) min = b;
v = max;
double d = max - min;
s = (max > 0.0) ? d/max : 0.0;
if (s == 0.0) {
h = UNDEFINED;
} else {
h = 60.0 * ((r == max) ? (g - b)/d : ((g == max) ? 2 + (b - r)/d : 4 + (r - g)/d));
if (h < 0) h += 360.0;
}
}
/*
* Convert HSV space to RGB space
*
* Inputs : h in the range [0,360) or UNDEFINED
* s, v in the range [0,1]
* Outputs : r, g, b in the range [0,1]
*
*/
void hsv_to_rgb(double h, double s, double v, double &r, double &g, double &b)
{
/* clip to the required range */
if (h != UNDEFINED) h -= 360.0 * ((h < 0.0) ? ceil(h/360.0) - 1 : floor(h/360.0));
s = (s > 1.0) ? 1.0 : ((s < 0.0) ? 0.0 : s);
v = (v > 1.0) ? 1.0 : ((v < 0.0) ? 0.0 : v);
if (s == 0.0) {
r = g = b = v;
} else {
h /= 60.0;
int i = int(floor(h));
float f = h - double(i);
float p = v * (1.0 - s);
float q = v * (1.0 - s * f);
float t = v * (1.0 - s * (1.0 - f));
switch (i) {
case 0 : r = v; g = t; b = p; break;
case 1 : r = q; g = v; b = p; break;
case 2 : r = p; g = v; b = t; break;
case 3 : r = p; g = q; b = v; break;
case 4 : r = t; g = p; b = v; break;
case 5 : r = v; g = p; b = q; break;
}
}
}
/*
* Convert RGB space to HLS space
*
* Inputs : r, g, b in the range [0,1]
* Outputs : h in the range [0,360) or UNDEFINED
* l, s in the range [0,1]
*/
void rgb_to_hls(double r, double g, double b, double &h, double &l, double &s)
{
/* clip to the required range */
r = (r > 1.0) ? 1.0 : ((r < 0.0) ? 0.0 : r);
g = (g > 1.0) ? 1.0 : ((g < 0.0) ? 0.0 : g);
b = (b > 1.0) ? 1.0 : ((b < 0.0) ? 0.0 : b);
double max = r, min = r;
if (g > max) max = g; if (g < min) min = g;
if (b > max) max = b; if (b < min) min = b;
l = (max + min) / 2.0;
if (max == min) {
s = 0.0;
h = UNDEFINED;
} else {
s = (l <= 0.5) ? (max - min)/(max + min) : (max - min)/(2.0 - max - min);
double d = max - min;
h = 60.0 * ((r == max) ? (g - b)/d : ((g == max) ? 2 + (b - r)/d : 4 + (r - g)/d));
if (h < 0.0) h += 360.0;
}
}
/*
* Convert HLS space to RGB space
*
* Inputs : h in the range [0,360) or UNDEFINED
* l, s in the range [0,1]
* Outputs : r, g, b in the range [0,1]
*
*/
/* Internal function */
double hls_internal(double n1, double n2, double h)
{
if (h > 360.0) h -= 360.0;
if (h < 0.0) h += 360.0;
if (h < 60.0) return n1 + (n2 - n1) * h / 60.0;
if (h < 180.0) return n2;
if (h < 240.0) return n1 + (n2 - n1) * (240.0 - h) / 60.0;
return n1;
}
void hls_to_rgb(double h, double l, double s, double &r, double &g, double &b)
{
/* clip to the required range */
if (h != UNDEFINED) h -= 360.0 * ((h < 0.0) ? ceil(h/360.0) - 1 : floor(h/360.0));
s = (s > 1.0) ? 1.0 : ((s < 0.0) ? 0.0 : s);
l = (l > 1.0) ? 1.0 : ((l < 0.0) ? 0.0 : l);
double m2 = (l <= 0.5) ? l * (1.0 + s) : l + s - l * s;
double m1 = 2 * l - m2;
if (s == 0) {
r = g = b = 1.0;
} else {
r = hls_internal(m1, m2, h + 120.0);
g = hls_internal(m1, m2, h);
b = hls_internal(m1, m2, h - 120.0);
}
}
Hope this helps,
Colm
-- Colm Buckley B.A. B.F. # colm at domain tuatha.org colm.buckley at domain tcd.ie colm at domain computer.org Department of Computer Science # +353 87 2469146 # whois cb3765 Trinity College, Dublin 2, Ireland. # http://www.tuatha.org/~colm/ All those who believe in psychokinesis raise my hand.
This archive was generated by hypermail 2.1.6 : Thu 06 Feb 2003 - 13:04:31 GMT