Sleipnir
src/color.cpp
00001 /*****************************************************************************
00002 * This file is provided under the Creative Commons Attribution 3.0 license.
00003 *
00004 * You are free to share, copy, distribute, transmit, or adapt this work
00005 * PROVIDED THAT you attribute the work to the authors listed below.
00006 * For more information, please see the following web page:
00007 * http://creativecommons.org/licenses/by/3.0/
00008 *
00009 * This file is a component of the Sleipnir library for functional genomics,
00010 * authored by:
00011 * Curtis Huttenhower (chuttenh@princeton.edu)
00012 * Mark Schroeder
00013 * Maria D. Chikina
00014 * Olga G. Troyanskaya (ogt@princeton.edu, primary contact)
00015 *
00016 * If you use this library, the included executable tools, or any related
00017 * code in your work, please cite the following publication:
00018 * Curtis Huttenhower, Mark Schroeder, Maria D. Chikina, and
00019 * Olga G. Troyanskaya.
00020 * "The Sleipnir library for computational functional genomics"
00021 *****************************************************************************/
00022 #include "stdafx.h"
00023 #include "color.h"
00024 #include "mathb.h"
00025 #include "meta.h"
00026 
00027 namespace Sleipnir {
00028 
00029 const CColor    CColor::c_Black     = CColor( 0x00, 0x00, 0x00 );
00030 const CColor    CColor::c_Cyan      = CColor( 0x00, 0xFF, 0xFF );
00031 const CColor    CColor::c_Green     = CColor( 0x00, 0xFF, 0x00 );
00032 const CColor    CColor::c_Red       = CColor( 0xFF, 0x00, 0x00 );
00033 const CColor    CColor::c_White     = CColor( 0xFF, 0xFF, 0xFF );
00034 const CColor    CColor::c_Yellow    = CColor( 0xFF, 0xFF, 0x00 );
00035 const CColor    CColor::c_Blue      = CColor( 0x00, 0x00, 0xFF );
00036 const CColor    CColor::c_DarkGreen = CColor( 0x00, 0x64, 0x00 );
00037 const CColor    CColor::c_Orange    = CColor( 0xFF, 0xA5, 0x00 );
00038 
00063 CColor CColor::Interpolate( float dValue, const CColor& ColorMinimum, const CColor& ColorMedium,
00064     const CColor& ColorMaximum ) {
00065     float           dOther;
00066     const CColor*   pOther;
00067 
00068     if( dValue < 0 )
00069         dValue = 0;
00070     else if( dValue > 1 )
00071         dValue = 1;
00072     dOther = 2 * dValue;
00073     if( dValue < 0.5 ) {
00074         pOther = &ColorMinimum;
00075         dOther = 1 - dOther; }
00076     else {
00077         pOther = &ColorMaximum;
00078         dOther -= 1; }
00079 
00080     return ( ( ColorMedium * ( 1 - dOther ) ) + ( *pOther * dOther ) ); }
00081 
00089 CColor::CColor( const unsigned char* abRGB ) {
00090     size_t  i;
00091 
00092     for( i = 0; i < c_iChannels; ++i )
00093         m_abRGB[ i ] = abRGB[ i ]; }
00094 
00108 CColor::CColor( unsigned char bRed, unsigned char bGreen, unsigned char bBlue ) {
00109 
00110     m_abRGB[ 0 ] = bRed;
00111     m_abRGB[ 1 ] = bGreen;
00112     m_abRGB[ 2 ] = bBlue; }
00113 
00124 CColor CColor::operator+( const CColor& Color ) const {
00125     size_t          ai[ c_iChannels ];
00126     unsigned char   ac[ c_iChannels ];
00127     size_t          i;
00128 
00129     for( i = 0; i < c_iChannels; ++i ) {
00130         if( ( ai[ i ] = m_abRGB[ i ] + Color.m_abRGB[ i ] ) > UCHAR_MAX )
00131             ai[ i ] = UCHAR_MAX;
00132         ac[ i ] = ai[ i ]; }
00133 
00134     return CColor( ac ); }
00135 
00146 CColor CColor::operator*( float dValue ) const {
00147     size_t          ai[ c_iChannels ];
00148     size_t          i;
00149     unsigned char   ac[ c_iChannels ];
00150 
00151     for( i = 0; i < c_iChannels; ++i ) {
00152         if( ( ai[ i ] = CMath::Round( m_abRGB[ i ] * dValue ) ) > UCHAR_MAX )
00153             ai[ i ] = UCHAR_MAX;
00154         ac[ i ] = ai[ i ]; }
00155 
00156     return CColor( ac ); }
00157 
00168 CColor& CColor::operator=( const CColor& Color ) {
00169     size_t  i;
00170 
00171     for( i = 0; i < c_iChannels; ++i )
00172         m_abRGB[ i ] = Color.m_abRGB[ i ];
00173 
00174     return *this; }
00175 
00186 string CColor::ToRGB( ) const {
00187     char    ac[ 7 ];
00188 
00189     sprintf_s( ac, ARRAYSIZE(ac), "%02x%02x%02x", m_abRGB[ 0 ], m_abRGB[ 1 ], m_abRGB[ 2 ] );
00190 
00191     return ac; }
00192 
00193 void CColorImpl::ToHSV( float& dHue, float& dSat, float& dVal ) const {
00194     float   dMin, dMax, dDelta;
00195     float   adRGB[ c_iChannels ];
00196     size_t  i;
00197 
00198     for( i = 0; i < c_iChannels; ++i )
00199         adRGB[ i ] = (float)m_abRGB[ i ] / UCHAR_MAX;
00200     dMin = dMax = adRGB[ 0 ];
00201     for( i = 1; i < c_iChannels; ++i ) {
00202         if( adRGB[ i ] < dMin )
00203             dMin = adRGB[ i ];
00204         if( adRGB[ i ] > dMax )
00205             dMax = adRGB[ i ]; }
00206 
00207     if( !( dVal = dMax ) ) {
00208         dSat = 0;
00209         dHue = -1;
00210         return; }       
00211     dDelta = dMax - dMin;
00212     dSat = dDelta / dMax;
00213 
00214     if( adRGB[ 0 ] == dMax )
00215         dHue = ( adRGB[ 1 ] - adRGB[ 2 ] ) / dDelta;
00216     else if( adRGB[ 1 ] == dMax )
00217         dHue = 2 + ( ( adRGB[ 2 ] - adRGB[ 0 ] ) / dDelta );
00218     else
00219         dHue = 4 + ( ( adRGB[ 0 ] - adRGB[ 1 ] ) / dDelta );
00220     if( ( dHue *= 60 ) < 0 )
00221         dHue += 360;
00222     dHue /= 360; }
00223 
00236 bool CColor::IsDark( ) const {
00237     float   dHue, dSat, dVal;
00238 
00239     ToHSV( dHue, dSat, dVal );
00240     
00241     return ( ( dVal < 0.5 ) || ( dHue < 0.05 ) || ( dHue > 0.666 ) ); }
00242 
00243 }