Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

include/cinder/Color.h

Go to the documentation of this file.
00001 /*
00002  Copyright (c) 2010, The Barbarian Group
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
00006  the following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and
00009     the following disclaimer.
00010     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
00011     the following disclaimer in the documentation and/or other materials provided with the distribution.
00012 
00013  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00014  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00015  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00016  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00017  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00018  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00019  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00020  POSSIBILITY OF SUCH DAMAGE.
00021 */
00022 
00023 #pragma once
00024 
00025 #include "cinder/Cinder.h"
00026 #include "cinder/ChanTraits.h"
00027 #include "cinder/Vector.h"
00028 #include "cinder/CinderMath.h"
00029 
00030 namespace cinder {
00031 
00032 typedef enum {
00033     CM_RGB, // Red[0 - 1.0] Green[0 - 1.0] Blue[0 - 1.0]
00034     CM_HSV  // Hue[0 - 1.0] Saturation[0 - 1.0] Value[0 - 1.0]
00035 } ColorModel;
00036 
00037 template<typename T>
00038 class ColorT 
00039 {
00040  public:
00041     T r,g,b;
00042 
00043     ColorT() : r( 0 ), g( 0 ), b( 0 ) {}
00044     ColorT( T aR, T aG, T aB ) 
00045         : r( aR ), g( aG ), b( aB )
00046     {}
00047     ColorT( const ColorT<T> &src ) 
00048         : r( src.r ), g( src.g ), b( src.b )
00049     {}
00050 
00051     ColorT( ColorModel cm, const Vec3f &v );
00052     ColorT( ColorModel cm, float x, float y, float z );
00053 
00054     template<typename FromT>
00055     ColorT( const ColorT<FromT> &src ) 
00056         : r( CHANTRAIT<T>::convert( src.r ) ), g( CHANTRAIT<T>::convert( src.g ) ), b( CHANTRAIT<T>::convert( src.b ) ) 
00057     {}
00058 
00059     void    set( ColorModel cm, const Vec3f &v );
00060 
00061     ColorT<T> operator=( const ColorT<T> &rhs ) 
00062     {
00063         r = rhs.r;
00064         g = rhs.g;
00065         b = rhs.b;
00066         return * this;
00067     }
00068 
00069     template<class FromT>
00070     ColorT<T> operator=( const ColorT<FromT> &rhs )
00071     {
00072         r = CHANTRAIT<T>::convert( rhs.r );
00073         g = CHANTRAIT<T>::convert( rhs.g );
00074         b = CHANTRAIT<T>::convert( rhs.b );
00075         return * this;
00076     }
00077 
00078     Vec3f get( ColorModel cm );
00079 
00080     T & operator[]( int n )
00081     {
00082         assert( n >= 0 && n <= 2 );
00083         if( 0 == n )
00084             return r;
00085         else if( 1 == n )
00086             return g;
00087         else
00088             return b;
00089     }
00090 
00091     ColorT<T>       operator+( const ColorT<T> &rhs ) const { return ColorT<T>( r + rhs.r, g + rhs.g, b + rhs.b ); }
00092     ColorT<T>       operator-( const ColorT<T> &rhs ) const { return ColorT<T>( r - rhs.r, g - rhs.g, b - rhs.b ); }
00093     ColorT<T>       operator*( const ColorT<T> &rhs ) const { return ColorT<T>( r * rhs.r, g * rhs.g, b * rhs.b ); }
00094     ColorT<T>       operator/( const ColorT<T> &rhs ) const { return ColorT<T>( r / rhs.r, g / rhs.g, b / rhs.b ); }
00095     const ColorT<T>&    operator+=( const ColorT<T> &rhs ) { r += rhs.r; g += rhs.g; b += rhs.b; return *this; }
00096     const ColorT<T>&    operator-=( const ColorT<T> &rhs ) { r -= rhs.r; g -= rhs.g; b -= rhs.b; return *this; }
00097     const ColorT<T>&    operator*=( const ColorT<T> &rhs ) { r *= rhs.r; g *= rhs.g; b *= rhs.b; return *this; }
00098     const ColorT<T>&    operator/=( const ColorT<T> &rhs ) { r /= rhs.r; g /= rhs.g; b /= rhs.b; return *this; }
00099     ColorT<T>       operator+( T rhs ) const { return ColorT<T>( r + rhs, g + rhs, b + rhs ); }
00100     ColorT<T>       operator-( T rhs ) const { return ColorT<T>( r - rhs, g - rhs, b - rhs ); }
00101     ColorT<T>       operator*( T rhs ) const { return ColorT<T>( r * rhs, g * rhs, b * rhs ); }
00102     ColorT<T>       operator/( T rhs ) const { return ColorT<T>( r / rhs, g / rhs, b / rhs ); }
00103     const ColorT<T>&    operator+=( T rhs ) { r += rhs; g += rhs; b += rhs; return *this; }
00104     const ColorT<T>&    operator-=( T rhs ) { r -= rhs; g -= rhs; b -= rhs; return *this; }
00105     const ColorT<T>&    operator*=( T rhs ) { r *= rhs; g *= rhs; b *= rhs; return *this; }
00106     const ColorT<T>&    operator/=( T rhs ) { r /= rhs; g /= rhs; b /= rhs; return *this; }
00107 
00108     typename CHANTRAIT<T>::Accum dot( const ColorT<T> &rhs ) const
00109     {
00110         return r*rhs.r + g*rhs.g + b*rhs.b;
00111     }
00112 
00113     float distance( const ColorT<T> &rhs ) const
00114     {
00115         return ( *this - rhs ).length();
00116     }
00117 
00118     typename CHANTRAIT<T>::Accum distanceSquared( const ColorT<T> &rhs ) const
00119     {
00120         return ( *this - rhs ).lengthSquared();
00121     }
00122 
00123     float length() const 
00124     {
00125         return math<float>::sqrt( static_cast<float>( r*r + g*g + b*b ) );
00126     }
00127 
00128     typename CHANTRAIT<T>::Accum lengthSquared() const 
00129     {
00130         return r*r + g*g + b*b;
00131     }
00132 
00133     // tests for zero-length
00134     void normalize()
00135     {
00136         float s = length();
00137         if( s > 0.0f ) {
00138             r = static_cast<T>( r / s );
00139             g = static_cast<T>( g / s );
00140             b = static_cast<T>( b / s );
00141         }
00142     }
00143 
00144     ColorT<T> lerp( T fact, const ColorT<T> &d ) const
00145     {
00146         return ColorT<T>( r + ( d.r - r ) * fact, g + ( d.g - g ) * fact, b + ( d.b - b ) * fact );
00147     }
00148 
00149     static ColorT<T> max()
00150     {
00151         return ColorT<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max() );
00152     }
00153 
00154     static ColorT<T> black()
00155     {
00156         return ColorT<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) );
00157     }
00158 
00159     static ColorT<T> white()
00160     {
00161         return ColorT<T>( static_cast<T>( 1 ), static_cast<T>( 1 ), static_cast<T>( 1 ) );
00162     }
00163 
00164     operator T*(){ return (T*) this; }
00165     operator const T*() const { return (const T*) this; }
00166 };
00167 
00168 template<typename T>
00169 std::ostream& operator<<( std::ostream &s, const ColorT<T> &v );
00170 
00171 
00173 // ColorAT
00174 
00175 template<typename T>
00176 class ColorAT {
00177  public: 
00178     T r,g,b,a;
00179 
00180     ColorAT() 
00181         : r( 0 ), g( 0 ), b( 0 ), a( 0 )
00182     {}
00183     ColorAT( T aR, T aG, T aB, T aA = CHANTRAIT<T>::convert( 1.0f ) )
00184         : r( aR ), g( aG ), b( aB ), a( aA )
00185     {}
00186     ColorAT( const ColorAT<T> &src ) 
00187         : r( src.r ), g( src.g ), b( src.b ), a( src.a )
00188     {}
00189     ColorAT( const ColorT<T> &col, T aA = CHANTRAIT<T>::convert( 1.0f ) )
00190         : r( col.r ), g( col.g ), b( col.b ), a( aA )
00191     {}
00192 
00193     ColorAT( ColorModel cm, float c1, float c2, float c3, float aA = CHANTRAIT<T>::convert( 1.0f ) );
00194 
00195     template<typename FromT>
00196     ColorAT( const ColorAT<FromT>& src )
00197         : r( CHANTRAIT<T>::convert( src.r ) ), g( CHANTRAIT<T>::convert( src.g ) ), b( CHANTRAIT<T>::convert( src.b ) ), a( CHANTRAIT<T>::convert( src.a ) )
00198     {}
00199 
00200     ColorAT<T> operator=( const ColorAT<T>& rhs ) 
00201     {
00202         r = rhs.r;
00203         g = rhs.g;
00204         b = rhs.b;
00205         a = rhs.a;
00206         return * this;
00207     }
00208 
00209     template<class FromT>
00210     ColorAT<T> operator=( const ColorAT<FromT>& rhs ) 
00211     {
00212         r = CHANTRAIT<T>::convert( rhs.r );
00213         g = CHANTRAIT<T>::convert( rhs.g );
00214         b = CHANTRAIT<T>::convert( rhs.b );
00215         a = CHANTRAIT<T>::convert( rhs.a );
00216         return * this;
00217     }
00218 
00219     T& operator[]( int n ) 
00220     {
00221         assert(n >= 0 && n <= 3);
00222         if( 0 == n ) 
00223             return r;
00224         else if( 1 == n ) 
00225             return g;
00226         else if( 2 == n ) 
00227             return b;
00228         else
00229             return a;
00230     }
00231 
00232     ColorAT<T>  operator+( const ColorAT<T> &rhs ) const { return ColorAT<T>( r + rhs.r, g + rhs.g, b + rhs.b, a + rhs.a ); }
00233     ColorAT<T>  operator-( const ColorAT<T> &rhs ) const { return ColorAT<T>( r - rhs.r, g - rhs.g, b - rhs.b, a - rhs.a ); }
00234     ColorAT<T>  operator*( const ColorAT<T> &rhs ) const { return ColorAT<T>( r * rhs.r, g * rhs.g, b * rhs.b, a * rhs.a ); }
00235     ColorAT<T>  operator/( const ColorAT<T> &rhs ) const { return ColorAT<T>( r / rhs.r, g / rhs.g, b / rhs.b, a / rhs.a ); }
00236     const ColorAT<T>&   operator+=( const ColorAT<T> &rhs ) { r += rhs.r; g += rhs.g; b += rhs.b; a += rhs.a; return *this; }
00237     const ColorAT<T>&   operator-=( const ColorAT<T> &rhs ) {   r -= rhs.r; g -= rhs.g; b -= rhs.b; a -= rhs.a; return *this; }
00238     const ColorAT<T>&   operator*=( const ColorAT<T> &rhs ) { r *= rhs.r; g *= rhs.g; b *= rhs.b; a *= rhs.a; return *this; }
00239     const ColorAT<T>&   operator/=( const ColorAT<T> &rhs ) {   r /= rhs.r; g /= rhs.g; b /= rhs.b; a /= rhs.a; return *this; }
00240     ColorAT<T>  operator+( T rhs ) const { return ColorAT<T>( r + rhs, g + rhs, b + rhs, a + rhs ); }
00241     ColorAT<T>  operator-( T rhs ) const { return ColorAT<T>( r - rhs, g - rhs, b - rhs, a - rhs ); }
00242     ColorAT<T>  operator*( T rhs ) const { return ColorAT<T>( r * rhs, g * rhs, b * rhs, a * rhs ); }
00243     ColorAT<T>  operator/( T rhs ) const { return ColorAT<T>( r / rhs, g / rhs, b / rhs, a / rhs ); }
00244     const ColorAT<T>&   operator+=( T rhs ) {   r += rhs; g += rhs; b += rhs; a += rhs; return *this; }
00245     const ColorAT<T>&   operator-=( T rhs ) {   r -= rhs; g -= rhs; b -= rhs; a -= rhs; return * this; }
00246     const ColorAT<T>&   operator*=( T rhs ) { r *= rhs; g *= rhs; b *= rhs; a *= rhs; return * this; }
00247     const ColorAT<T>&   operator/=( T rhs ) { r /= rhs; g /= rhs; b /= rhs; a /= rhs;   return * this; }
00248 
00249     float length() const
00250     {
00251         return math<float>::sqrt( static_cast<float>( r*r + g*g + b*b ) );
00252     }
00253 
00254     // tests for zero-length
00255     void normalize()
00256     {
00257         float s = length();
00258         if( s > 0.0f ) {
00259             r = static_cast<T>( r / s );
00260             g = static_cast<T>( g / s );
00261             b = static_cast<T>( b / s );
00262         }
00263     }
00264 
00265     ColorAT<T> premultiplied() const
00266     {
00267         return ColorAT<T>( r * a, g * a, b * a, a );
00268     }
00269 
00270     typename CHANTRAIT<T>::Accum lengthSquared() const
00271     {
00272         return r * r + g * g + b * b;
00273     }
00274 
00275     ColorAT<T> lerp( T fact, const ColorAT<T> &d ) const
00276     {
00277         return ColorAT<T>( r + ( d.r - r ) * fact, g + ( d.g - g ) * fact, b + ( d.b - b ) * fact, a + ( d.a - a ) * fact );
00278     }
00279 
00280     static ColorAT<T> zero()
00281     {
00282         return ColorAT<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) );
00283     }
00284 
00285     static ColorAT<T> black()
00286     {
00287         return zero();
00288     }
00289 
00290     operator T*(){ return (T*) this; }
00291     operator const T*() const { return (const T*) this; }
00292     operator ColorT<T>(){ return ColorT<T>( r, g, b ); }
00293 };
00294 
00295 template<typename T>
00296 std::ostream& operator<<( std::ostream &lhs, const ColorAT<T> &rhs );
00297 
00298 // Free Functions
00299 
00300 extern ColorT<float> hsvToRGB( const Vec3f &hsv );
00301 extern Vec3f rgbToHSV( const ColorT<float> &c );
00302 
00303 typedef ColorT<float>       Color;
00304 typedef ColorT<float>       Colorf;
00305 typedef ColorT<uint8_t>     Color8u;
00306 typedef ColorAT<float>      ColorA;
00307 typedef ColorAT<float>      ColorAf;
00308 typedef ColorAT<uint8_t>    ColorA8u;
00309 
00310 } // namespace cinder