A True Color Wheel | CodeGuru

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 […]

Written By
CodeGuru Staff
CodeGuru Staff
Aug 1, 1999
1 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

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.

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.