00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #pragma once
00027
00028 #include "cinder/Cinder.h"
00029 #include "cinder/ChanTraits.h"
00030 #include "cinder/Vector.h"
00031 #include "cinder/CinderMath.h"
00032
00033 namespace cinder {
00034
00035 typedef enum {
00036 CM_RGB,
00037 CM_HSV
00038 } ColorModel;
00039
00040 template<typename T>
00041 class ColorT
00042 {
00043 public:
00044 T r,g,b;
00045
00046 ColorT() : r( 0 ), g( 0 ), b( 0 ) {}
00047 ColorT( T aR, T aG, T aB )
00048 : r( aR ), g( aG ), b( aB )
00049 {}
00050 ColorT( const ColorT<T> &src )
00051 : r( src.r ), g( src.g ), b( src.b )
00052 {}
00053
00054 ColorT( ColorModel cm, const Vec3f &v );
00055 ColorT( ColorModel cm, float x, float y, float z );
00056
00057 template<typename FromT>
00058 ColorT( const ColorT<FromT> &src )
00059 : r( CHANTRAIT<T>::convert( src.r ) ), g( CHANTRAIT<T>::convert( src.g ) ), b( CHANTRAIT<T>::convert( src.b ) )
00060 {}
00061
00062 void set( ColorModel cm, const Vec3f &v );
00063
00064 ColorT<T> operator=( const ColorT<T> &rhs )
00065 {
00066 r = rhs.r;
00067 g = rhs.g;
00068 b = rhs.b;
00069 return * this;
00070 }
00071
00072 template<class FromT>
00073 ColorT<T> operator=( const ColorT<FromT> &rhs )
00074 {
00075 r = CHANTRAIT<T>::convert( rhs.r );
00076 g = CHANTRAIT<T>::convert( rhs.g );
00077 b = CHANTRAIT<T>::convert( rhs.b );
00078 return * this;
00079 }
00080
00081 Vec3f get( ColorModel cm ) const;
00082
00083 T& operator[]( int n )
00084 {
00085 assert( n >= 0 && n <= 2 );
00086 return (&r)[n];
00087 }
00088
00089 const T& operator[]( int n ) const
00090 {
00091 assert( n >= 0 && n <= 2 );
00092 return (&r)[n];
00093 }
00094
00095 T* ptr() const { return &(const_cast<ColorT*>( this )->r); }
00096
00097 ColorT<T> operator+( const ColorT<T> &rhs ) const { return ColorT<T>( r + rhs.r, g + rhs.g, b + rhs.b ); }
00098 ColorT<T> operator-( const ColorT<T> &rhs ) const { return ColorT<T>( r - rhs.r, g - rhs.g, b - rhs.b ); }
00099 ColorT<T> operator*( const ColorT<T> &rhs ) const { return ColorT<T>( r * rhs.r, g * rhs.g, b * rhs.b ); }
00100 ColorT<T> operator/( const ColorT<T> &rhs ) const { return ColorT<T>( r / rhs.r, g / rhs.g, b / rhs.b ); }
00101 const ColorT<T>& operator+=( const ColorT<T> &rhs ) { r += rhs.r; g += rhs.g; b += rhs.b; return *this; }
00102 const ColorT<T>& operator-=( const ColorT<T> &rhs ) { r -= rhs.r; g -= rhs.g; b -= rhs.b; return *this; }
00103 const ColorT<T>& operator*=( const ColorT<T> &rhs ) { r *= rhs.r; g *= rhs.g; b *= rhs.b; return *this; }
00104 const ColorT<T>& operator/=( const ColorT<T> &rhs ) { r /= rhs.r; g /= rhs.g; b /= rhs.b; return *this; }
00105 ColorT<T> operator+( T rhs ) const { return ColorT<T>( r + rhs, g + rhs, b + rhs ); }
00106 ColorT<T> operator-( T rhs ) const { return ColorT<T>( r - rhs, g - rhs, b - rhs ); }
00107 ColorT<T> operator*( T rhs ) const { return ColorT<T>( r * rhs, g * rhs, b * rhs ); }
00108 ColorT<T> operator/( T rhs ) const { return ColorT<T>( r / rhs, g / rhs, b / rhs ); }
00109 const ColorT<T>& operator+=( T rhs ) { r += rhs; g += rhs; b += rhs; return *this; }
00110 const ColorT<T>& operator-=( T rhs ) { r -= rhs; g -= rhs; b -= rhs; return *this; }
00111 const ColorT<T>& operator*=( T rhs ) { r *= rhs; g *= rhs; b *= rhs; return *this; }
00112 const ColorT<T>& operator/=( T rhs ) { r /= rhs; g /= rhs; b /= rhs; return *this; }
00113
00114 bool operator==( const ColorT<T>& rhs ) const
00115 {
00116 return ( r == rhs.r ) && ( g == rhs.g ) && ( b == rhs.b );
00117 }
00118
00119 bool operator!=( const ColorT<T>& rhs ) const
00120 {
00121 return ! ( *this == rhs );
00122 }
00123
00124 typename CHANTRAIT<T>::Accum dot( const ColorT<T> &rhs ) const
00125 {
00126 return r*rhs.r + g*rhs.g + b*rhs.b;
00127 }
00128
00129 float distance( const ColorT<T> &rhs ) const
00130 {
00131 return math<float>::sqrt( static_cast<float>( (r - rhs.r)*(r - rhs.r) + (g - rhs.g)*(g - rhs.g) + (b - rhs.b)*(b - rhs.b)) );
00132 }
00133
00134 typename CHANTRAIT<T>::Accum distanceSquared( const ColorT<T> &rhs ) const
00135 {
00136 return (r - rhs.r) * (r - rhs.r) + (g - rhs.g) * (g - rhs.g) + (b - rhs.b) * (b - rhs.b);
00137 }
00138
00139 float length() const
00140 {
00141 return math<float>::sqrt( static_cast<float>( r*r + g*g + b*b ) );
00142 }
00143
00144 typename CHANTRAIT<T>::Accum lengthSquared() const
00145 {
00146 return r*r + g*g + b*b;
00147 }
00148
00149
00150 void normalize()
00151 {
00152 float s = length();
00153 if( s > 0.0f ) {
00154 r = static_cast<T>( r / s );
00155 g = static_cast<T>( g / s );
00156 b = static_cast<T>( b / s );
00157 }
00158 }
00159
00160 ColorT<T> lerp( float fact, const ColorT<T> &d ) const
00161 {
00162 return ColorT<T>( r + ( d.r - r ) * fact, g + ( d.g - g ) * fact, b + ( d.b - b ) * fact );
00163 }
00164
00165 static ColorT<T> max()
00166 {
00167 return ColorT<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max() );
00168 }
00169
00170 static ColorT<T> black()
00171 {
00172 return ColorT<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) );
00173 }
00174
00175 static ColorT<T> white()
00176 {
00177 return ColorT<T>( CHANTRAIT<T>::max(), CHANTRAIT<T>::max(), CHANTRAIT<T>::max() );
00178 }
00179
00180 static ColorT<T> gray( T value )
00181 {
00182 return ColorT<T>( value, value, value );
00183 }
00184
00186 static ColorT<T> hex( uint32_t hexValue )
00187 {
00188 uint8_t red = ( hexValue >> 16 ) & 255;
00189 uint8_t green = ( hexValue >> 8 ) & 255;
00190 uint8_t blue = hexValue & 255;
00191 return ColorT<T>( CHANTRAIT<T>::convert( red ), CHANTRAIT<T>::convert( green ), CHANTRAIT<T>::convert( blue ) );
00192 }
00193
00194 operator T*(){ return (T*) this; }
00195 operator const T*() const { return (const T*) this; }
00196 };
00197
00198
00200
00201
00202 template<typename T>
00203 class ColorAT {
00204 public:
00205 T r,g,b,a;
00206
00207 ColorAT()
00208 : r( 0 ), g( 0 ), b( 0 ), a( 0 )
00209 {}
00210 ColorAT( T aR, T aG, T aB, T aA = CHANTRAIT<T>::convert( 1.0f ) )
00211 : r( aR ), g( aG ), b( aB ), a( aA )
00212 {}
00213 ColorAT( const ColorAT<T> &src )
00214 : r( src.r ), g( src.g ), b( src.b ), a( src.a )
00215 {}
00216 ColorAT( const ColorT<T> &col, T aA = CHANTRAIT<T>::convert( 1.0f ) )
00217 : r( col.r ), g( col.g ), b( col.b ), a( aA )
00218 {}
00219
00220 ColorAT( ColorModel cm, float c1, float c2, float c3, float aA = CHANTRAIT<T>::convert( 1.0f ) );
00221
00222 template<typename FromT>
00223 ColorAT( const ColorT<FromT> &src )
00224 : r( CHANTRAIT<T>::convert( src.r ) ), g( CHANTRAIT<T>::convert( src.g ) ), b( CHANTRAIT<T>::convert( src.b ) ), a( CHANTRAIT<T>::convert( 1.0f ) )
00225 {}
00226
00227
00228 template<typename FromT>
00229 ColorAT( const ColorAT<FromT>& src )
00230 : r( CHANTRAIT<T>::convert( src.r ) ), g( CHANTRAIT<T>::convert( src.g ) ), b( CHANTRAIT<T>::convert( src.b ) ), a( CHANTRAIT<T>::convert( src.a ) )
00231 {}
00232
00233 ColorAT<T> operator=( const ColorAT<T>& rhs )
00234 {
00235 r = rhs.r;
00236 g = rhs.g;
00237 b = rhs.b;
00238 a = rhs.a;
00239 return * this;
00240 }
00241
00242 template<class FromT>
00243 ColorAT<T> operator=( const ColorAT<FromT>& rhs )
00244 {
00245 r = CHANTRAIT<T>::convert( rhs.r );
00246 g = CHANTRAIT<T>::convert( rhs.g );
00247 b = CHANTRAIT<T>::convert( rhs.b );
00248 a = CHANTRAIT<T>::convert( rhs.a );
00249 return * this;
00250 }
00251
00252 T& operator[]( int n )
00253 {
00254 assert( n >= 0 && n <= 3 );
00255 return (&r)[n];
00256 }
00257
00258 const T& operator[]( int n ) const
00259 {
00260 assert( n >= 0 && n <= 3 );
00261 return (&r)[n];
00262 }
00263
00264 T* ptr() const { return &(const_cast<ColorAT*>( this )->r); }
00265
00266 ColorAT<T> operator+( const ColorAT<T> &rhs ) const { return ColorAT<T>( r + rhs.r, g + rhs.g, b + rhs.b, a + rhs.a ); }
00267 ColorAT<T> operator-( const ColorAT<T> &rhs ) const { return ColorAT<T>( r - rhs.r, g - rhs.g, b - rhs.b, a - rhs.a ); }
00268 ColorAT<T> operator*( const ColorAT<T> &rhs ) const { return ColorAT<T>( r * rhs.r, g * rhs.g, b * rhs.b, a * rhs.a ); }
00269 ColorAT<T> operator/( const ColorAT<T> &rhs ) const { return ColorAT<T>( r / rhs.r, g / rhs.g, b / rhs.b, a / rhs.a ); }
00270 const ColorAT<T>& operator+=( const ColorAT<T> &rhs ) { r += rhs.r; g += rhs.g; b += rhs.b; a += rhs.a; return *this; }
00271 const ColorAT<T>& operator-=( const ColorAT<T> &rhs ) { r -= rhs.r; g -= rhs.g; b -= rhs.b; a -= rhs.a; return *this; }
00272 const ColorAT<T>& operator*=( const ColorAT<T> &rhs ) { r *= rhs.r; g *= rhs.g; b *= rhs.b; a *= rhs.a; return *this; }
00273 const ColorAT<T>& operator/=( const ColorAT<T> &rhs ) { r /= rhs.r; g /= rhs.g; b /= rhs.b; a /= rhs.a; return *this; }
00274 ColorAT<T> operator+( T rhs ) const { return ColorAT<T>( r + rhs, g + rhs, b + rhs, a + rhs ); }
00275 ColorAT<T> operator-( T rhs ) const { return ColorAT<T>( r - rhs, g - rhs, b - rhs, a - rhs ); }
00276 ColorAT<T> operator*( T rhs ) const { return ColorAT<T>( r * rhs, g * rhs, b * rhs, a * rhs ); }
00277 ColorAT<T> operator/( T rhs ) const { return ColorAT<T>( r / rhs, g / rhs, b / rhs, a / rhs ); }
00278 const ColorAT<T>& operator+=( T rhs ) { r += rhs; g += rhs; b += rhs; a += rhs; return *this; }
00279 const ColorAT<T>& operator-=( T rhs ) { r -= rhs; g -= rhs; b -= rhs; a -= rhs; return * this; }
00280 const ColorAT<T>& operator*=( T rhs ) { r *= rhs; g *= rhs; b *= rhs; a *= rhs; return * this; }
00281 const ColorAT<T>& operator/=( T rhs ) { r /= rhs; g /= rhs; b /= rhs; a /= rhs; return * this; }
00282
00283 bool operator==( const ColorAT<T>& rhs ) const
00284 {
00285 return ( r == rhs.r ) && ( g == rhs.g ) && ( b == rhs.b ) && ( a == rhs.a );
00286 }
00287
00288 bool operator!=( const ColorAT<T>& rhs ) const
00289 {
00290 return ! ( *this == rhs );
00291 }
00292
00293 float length() const
00294 {
00295 return math<float>::sqrt( static_cast<float>( r*r + g*g + b*b ) );
00296 }
00297
00298
00299 void normalize()
00300 {
00301 float s = length();
00302 if( s > 0.0f ) {
00303 r = static_cast<T>( r / s );
00304 g = static_cast<T>( g / s );
00305 b = static_cast<T>( b / s );
00306 }
00307 }
00308
00309 ColorAT<T> premultiplied() const
00310 {
00311 return ColorAT<T>( r * a, g * a, b * a, a );
00312 }
00313
00314 typename CHANTRAIT<T>::Accum lengthSquared() const
00315 {
00316 return r * r + g * g + b * b;
00317 }
00318
00319 ColorAT<T> lerp( T fact, const ColorAT<T> &d ) const
00320 {
00321 return ColorAT<T>( r + ( d.r - r ) * fact, g + ( d.g - g ) * fact, b + ( d.b - b ) * fact, a + ( d.a - a ) * fact );
00322 }
00323
00324 static ColorAT<T> zero()
00325 {
00326 return ColorAT<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) );
00327 }
00328
00329 static ColorAT<T> black()
00330 {
00331 return ColorAT<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), CHANTRAIT<T>::max() );
00332 }
00333
00334 static ColorAT<T> white()
00335 {
00336 return ColorAT<T>( CHANTRAIT<T>::max(), CHANTRAIT<T>::max(), CHANTRAIT<T>::max(), CHANTRAIT<T>::max() );
00337 }
00338
00339 static ColorAT<T> gray( T value, T alpha = CHANTRAIT<T>::max() )
00340 {
00341 return ColorAT<T>( value, value, value, alpha );
00342 }
00343
00345 static ColorAT<T> hex( uint32_t hexValue )
00346 {
00347 uint8_t red = ( hexValue >> 16 ) & 255;
00348 uint8_t green = ( hexValue >> 8 ) & 255;
00349 uint8_t blue = hexValue & 255;
00350 return ColorAT<T>( CHANTRAIT<T>::convert( red ), CHANTRAIT<T>::convert( green ), CHANTRAIT<T>::convert( blue ), CHANTRAIT<T>::max() );
00351 }
00352
00354 static ColorAT<T> hexA( uint32_t hexValue )
00355 {
00356 uint8_t alpha = ( hexValue >> 24 ) & 255;;
00357 uint8_t red = ( hexValue >> 16 ) & 255;
00358 uint8_t green = ( hexValue >> 8 ) & 255;
00359 uint8_t blue = hexValue & 255;
00360 return ColorAT<T>( CHANTRAIT<T>::convert( red ), CHANTRAIT<T>::convert( green ), CHANTRAIT<T>::convert( blue ), CHANTRAIT<T>::convert( alpha ) );
00361 }
00362
00363 operator T*(){ return (T*) this; }
00364 operator const T*() const { return (const T*) this; }
00365 operator ColorT<T>(){ return ColorT<T>( r, g, b ); }
00366 };
00367
00368
00369 template <typename T, typename Y> inline ColorT<T> operator*( Y s, const ColorT<T>& c ) { return ColorT<T>( s*c.r, s*c.g, s*c.b ); }
00370 template <typename T, typename Y> inline ColorAT<T> operator*( Y s, const ColorAT<T>& c ) { return ColorAT<T>( s*c.r, s*c.g, s*c.b, s*c.a ); }
00371
00372
00373 extern ColorT<float> hsvToRGB( const Vec3f &hsv );
00374 extern Vec3f rgbToHSV( const ColorT<float> &c );
00375
00376 extern std::ostream& operator<<( std::ostream &lhs, const ColorT<float> &rhs );
00377 extern std::ostream& operator<<( std::ostream &lhs, const ColorAT<float> &rhs );
00378 extern std::ostream& operator<<( std::ostream &lhs, const ColorT<uint8_t> &rhs );
00379 extern std::ostream& operator<<( std::ostream &lhs, const ColorAT<uint8_t> &rhs );
00380
00381 typedef ColorT<float> Color;
00382 typedef ColorT<float> Colorf;
00383 typedef ColorT<uint8_t> Color8u;
00384 typedef ColorAT<float> ColorA;
00385 typedef ColorAT<float> ColorAf;
00386 typedef ColorAT<uint8_t> ColorA8u;
00387
00388 }