A True Color Wheel

Environment: VC4

The following is a code snippet written in VC++ 4.0. It generates a CArray of COLORREF objects that forms a true color circle. The two input parameters are integers in the range of 0 to 5 to accomodate two sets of radio buttons in a dialog box. I developed this routine to use in a Mandelbrot fractal generator program. It can be used in math displays where the color indicates phase shift.

The requirements that I set are that the three primary colors (red, green, blue) be guaranteed pure and that shadings be evenly spaced. This leads to the palette sizes being solutions to 3 * 2^n (3 < (int)n < 8). This way the palette starts at a reasonable size and run to the resolution of 24 bit systems. A bug in the 4.0 compiler led me to write this as in-line code rather than a separate function. 4.0 doesn't like accessing template arrays from within a function. The generation code may be written as a separate function in later MFC releases (untested).

Even brightness is achieved by ramping the colors up and down with the sine/cosine function from 0 to pi/2. I left the ramp calculations unoptimized so that the equations are more decipherable (ie. 256 * pi / 2 instead of 128 * pi). Even so, the VC compiler will optimize this calculation for us.


// Input variables. both are in range of 0-5 to work with
// dialog box radio buttons.
// Color shift radio buttons are arranged for the three primary colors
// (Blue, Green Red) in the top row of a 3X2 arrangement and the 
// complementary color (Yellow, Magenta, Cyan) in the bottom row.
// Palette generates Blue-Red-Green-Blue sequence as written.
// Palette sizes are calculated by 3 * 2^n (3 < (int)n < 8).
int nPalSize;
int nColorShift;
double pi = 3.1415926535;

// Generate color palette.
// Colors represent the outer edge of a 24 bit (maximum) color palette.
// Colors are equally spaced around the edge of the color circle.
// Use CArray object to use functions and dynamic sizing.
CArray m_colorArray;

// Arrays to translate palette size and color shift
// from parameter array integers. Initial integers
// correspond to radio button values in parameter
// dialog box.
int PalSizeArray[] = { 24, 48, 96, 192, 384, 768 };
// Color shift blue, green, red, yellow, magenta, cyan
int ColorShiftArray[] = { 0, 511, 255, 383, 127, 639 };

nPalSize = PalSizeArray[ nPalSize ];
nColorShift = ColorShiftArray[ nColorShift ];

// First range check
if ( nPalSize > 768 )
	nPalSize = 768;
if ( nPalSize < 24 )
	nPalSize = 24;

// Now set the array size. May be one too big after modifications.
// At least not harmful.
m_colorArray.SetSize( nPalSize + 1 );

// Then set the palette
	
for ( int n = 0; n <= nPalSize; ++n )
{
	// nFactor calculate position of n in maximized palette ( 768 total colors )
	int nFactor;
	int nRed, nGreen, nBlue;
	nFactor = 768 * n / nPalSize;	// Assure that it runs 0 to 768
	nFactor = nFactor + nColorShift;
	if ( nFactor >= 768 )			// Adjust for color shift
		nFactor = nFactor - 768;

	// Color calculations include sine/cosine functions to create
	// colors at constant radius from center of color circle. This
	// creates a constant brightness level. Math not optimized, left in readable state.
	if ( nFactor <= 256 )
	{
		// Red increasing, no green, blue decreasing
		nRed = int( (double)255 * (sin( ( (double)nFactor/256) * pi / 2 ) ) );
		nGreen = 0;
		nBlue = int( (double)255 * (cos( ( (double)nFactor/256) * pi / 2 ) ) );
		m_colorArray.SetAt( n, COLORREF( RGB( nRed, nGreen, nBlue ) ) );
	}
	else if ( ( nFactor > 256 ) && ( nFactor <= 512 ) )
	{
		// Red decreasing, green increasing, blue 0.
		nRed = int( (double)255 * (cos( ( (double)(nFactor - 256 ) /256) * pi / 2 ) ) );
		nGreen =  int( (double)255 * (sin( ( (double)(nFactor - 256 ) /256) * pi / 2 ) ) );
		nBlue = 0;
		m_colorArray.SetAt( n, COLORREF( RGB( nRed, nGreen, nBlue ) ) );
	}
	else if ( ( nFactor > 512 ) )
	{
		// Red 0, green decreasing, blue increasing
		nRed = 0;
		nGreen =  int( (double)255 * (cos( ( (double)(nFactor - 512 ) /256) * pi / 2 ) ) );
		nBlue = int( (double)255 * (sin( ( (double)(nFactor - 512 ) /256) * pi / 2 ) ) );
		m_colorArray.SetAt( n, COLORREF( RGB( nRed, nGreen, nBlue ) ) );
	}
}

// Now there is CArray of COLORREF objects of nPalSize size.
// The palette guarantees a pure red, blue and green with
// constant brightness and even spacing of colors between primaries.
// If the color shift is set to a secondary color (cyan, magenta
// yellow) then the seconday colors are guaranteed pure.



Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: November 20, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Are you wanting to target two or more platforms such as iOS, Android, and/or Windows? You are not alone. 90% of enterprises today are targeting two or more platforms. Attend this eSeminar to discover how mobile app developers can rely on one IDE to create applications across platforms and approaches (web, native, and/or hybrid), saving time, money, and effort and introducing apps to market faster. You'll learn the trade-offs for gaining long …

  • IBM Worklight is a mobile application development platform that lets you extend your business to mobile devices. It is designed to provide an open, comprehensive platform to build, run and manage HTML5, hybrid and native mobile apps.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds