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: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • Hundreds of millions of users have adopted public cloud storage solutions to satisfy their Private Online File Sharing and Collaboration (OFS) needs. With new headlines on cloud privacy issues appearing almost daily, the need to explore private alternatives has never been stronger. Join ESG Senior Analyst Terri McClure and Connected Data in this on-demand webinar to take a look at the business drivers behind OFS adoption, how organizations can benefit from on-premise deployments, and emerging private OFS …

Most Popular Programming Stories

More for Developers

RSS Feeds