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

  • Organizations are increasingly gravitating toward mobile-first application development as they assess the need to revamp their application portfolios to support touch computing and mobility. Consumerization has brought higher expectations for application usability along with the mobile devices themselves. Enterprises are increasingly shifting their new application acquisitions and development efforts toward mobile platforms. With this backdrop, it is natural to expect application platform vendors to invest in …

  • On-demand Event Event Date: June 23, 2015 Business transformation is not just important, it is vital to the success of all organizations in the 21st century marketplace. How IT approaches and executes the move from cost center to revenue contributor will not only transform the IT organization, it will change how companies retain competitive advantage and meet the requirements of internal and external customers. This shift in thinking is not new, but actualizing it is. Check out this eSeminar to learn the …

Most Popular Programming Stories

More for Developers

RSS Feeds

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