# 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