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: September 23, 2015 @ 1:00 p.m. ET / 10:00 a.m. PT The cloud is not just about a runtime platform for your projects – now, you can do your development in the cloud, too. Check out this upcoming eseminar to learn how the cloud improves your development experience and team collaboration. Join Dana Singleterry, Principal Product Manager for Oracle Dev Tools, as he discusses how to simplify every aspect of the development lifecycle, including requirements gathering, version management, code …

  • Lenovo recommends Windows 8 Pro. "I dropped my laptop getting out of the taxi." This probably sounds familiar to most IT professionals. If your employees are traveling, you know their devices are in for a rough go. Whether it's a trip to the conference room or a convention out of town, any time equipment leaves a user's desk it is at risk of being put into harm's way. Stay connected at all times, whether at the office or on the go, with agile, durable, and flexible devices like the Lenovo® …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date