Color Wheel

index -|- home

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 ...

Color wheel image

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 ...


top

checked by tidy  Valid HTML 4.01 Transitional