00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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,
00034 CM_HSV
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
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
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
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
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 }