This is a generated color wheel bitmap ... where the outer edge is white, RGB(255,255,255), and the center is black, RGB(0,0,0) ... outside the circle is BLACK ...
This bitmap is actually 257 x 257, here expanded to 514 x 514 ... it shows the RGB colors arranged in a circle ... any bands or physical areas are indications of the particular display capability ... in essence, it represent all 16 million colors available from RGB (256 x 256 x 256) = 16,777,216 colors - or as called "True Color" ... but is actually a point by point generation ...
This is bitmap is generated and written by my testap1/genwheel console application ... the bitmap is generated from the function gen_color_wheel(), which creates and writes to a bitmap file using the 257 x 257 series -
for( y = 256; y >= 0; y-- ) { for( x = 0; x <= 256; x++ ) { char * cp = get_color_point( x, y ); // get #RRGGBB string // ... and from this generated color, fill in an RGB scan line ... sb[0] = cp[1]; sb[1] = cp[2]; sb[2] = 0; sscanf(sb, "%X", &r); sb[0] = cp[3]; sb[1] = cp[4]; sb[2] = 0; sscanf(sb, "%X", &g); sb[0] = cp[5]; sb[1] = cp[6]; sb[2] = 0; sscanf(sb, "%X", &b); iswhite = 1; if( strcmp(cp, "#FFFFFF") ) { iswhite = 0; } if( iswhite ) { r = g = b = 0; // convert WHITE to BLACK } bp = &scanline[ x * 3 ]; bp[0] = (byte)b; bp[1] = (byte)g; bp[2] = (byte)r; } fwrite( scanline, 1, bytewidth, out ); }
The get_color_point( x, y ) function uses the ( x, y ) point to generate a color for that point. If it is outside the circle it generated 'black', else it generates a color within the circle ... for the values, x, and y -
char * get_color_point( int x, int y ) { int cartx = x - 128; int carty = 128 - y; int cartx2 = cartx * cartx; int carty2 = carty * carty; double rraw = sqrt(cartx2 + carty2); //raw radius rnorm = rraw / 128; //normalized radius if (rraw == 0) { sprintf(cp,"#%2.2X%2.2X%2.2X", 0, 0, 0); // set BLACK } else { double arad = acos(cartx / rraw); //angle in radians double aradc = (carty >= 0) ? arad : (2 * M_PI) - arad; //correct below axis double adeg = 360 * aradc / (2 * M_PI); //convert to degrees if (rnorm > 1.0) { // outside circle sprintf(cp,"#%2.2X%2.2X%2.2X", 255, 255, 255); } else if (rnorm >= 0.5) { sat = 1 - ((rnorm - 0.5) * 2 ); val = 1; cp = hsv2rgb2(adeg,sat,val); } else { sat = 1; val = rnorm * 2; cp = hsv2rgb2(adeg,sat,val); } } return cp; }
The essentials of the hsv2rgb2(degrees, saturation, value) function are -
char * hsv2rgb2( double Hdeg, double S, double V ) { static char _s_clr2[16]; char * cp = _s_clr2; double H; int R,G,B, var_i; double var_r, var_g, var_b; double var_1, var_2, var_3; H = Hdeg / 360.0; // convert from degrees to 0 to 1 if (S == 0.0) { // HSV values = From 0 to 1 R = (int)(V * 255); // RGB results = From 0 to 255 G = (int)(V * 255); B = (int)(V * 255); } else { double var_h = H * 6; var_i = (int) var_h; //Or ... var_i = floor( var_h ) var_1 = V * (1 - S); var_2 = V * (1 - S * (var_h - var_i)); var_3 = V * (1 - S * (1 - ( var_h - var_i) ) ); if (var_i == 0 ) { var_r = V; var_g = var_3; var_b = var_1; } else if (var_i == 1 ) { var_r = var_2; var_g = V; var_b = var_1; } else if (var_i == 2 ) { var_r = var_1; var_g = V; var_b = var_3; } else if (var_i == 3 ) { var_r = var_1; var_g = var_2; var_b = V; } else if (var_i == 4 ) { var_r = var_3; var_g = var_1; var_b = V; } else { var_r = V; var_g = var_1; var_b = var_2; } R = round(var_r * 255); //RGB results = From 0 to 255 G = round(var_g * 255); B = round(var_b * 255); } sprintf( cp, "#%2.2X%2.2X%2.2X", R, G, B ); return cp; }
This result from the hsv2rgb2() functions is split into the RGB values returned ... and used to build the scanline values .. to write to the bitmap generated ... a color circle ... this whole function was adapted from a Perl (CGI) function to do the same thing ...