Page principale | Hi�rarchie des classes | Liste des classes | Liste des fichiers | Membres de classe | Membres de fichier

Color.cpp

Aller � la documentation de ce fichier.
00001 /// \file 00002 /// Impl�mentation des classes utiles pour la gestion des couleurs 00003 #include "Color.hpp" 00004 /////////////////////////////////////////////////////////////////////////////// 00005 /// Classe : Color 00006 /////////////////////////////////////////////////////////////////////////////// 00007 Color::Color(){ 00008 p = new Color_Gray(0); 00009 } 00010 Color::Color(float gray){ 00011 p = new Color_Gray(gray); 00012 } 00013 Color::Color(float red, float green, float blue, bool rgb){ 00014 p = new Color_Color(red, green, blue, rgb); 00015 } 00016 Color::Color(const Color& color){ 00017 p = color.p; 00018 ++p->use; 00019 } 00020 Color& Color::operator=(const Color& rhs){ 00021 rhs.p->use++; 00022 if(--p->use == 0){ 00023 delete p; 00024 } 00025 p = rhs.p; 00026 return *this; 00027 } 00028 Color::~Color(){ 00029 if(--p->use == 0){ 00030 delete p; 00031 } 00032 } 00033 ECOLOR_TYPE Color::getType()const{ 00034 return p->getType(); 00035 } 00036 string Color::toString() const{ 00037 return p->toString(); 00038 } 00039 float Color::getGray() const{ 00040 return p->getGray(); 00041 } 00042 float Color::getRed() const{ 00043 return p->getRed(); 00044 } 00045 float Color::getGreen() const{ 00046 return p->getGreen(); 00047 } 00048 float Color::getBlue() const{ 00049 return p->getBlue(); 00050 } 00051 float Color::getHue()const{ 00052 return p->getHue(); 00053 } 00054 float Color::getSaturation()const{ 00055 return p->getSaturation(); 00056 } 00057 float Color::getValue()const{ 00058 return p->getValue(); 00059 } 00060 float* Color::getFloat(bool rgb)const{ 00061 float* ret = new float[3]; 00062 if(rgb){ 00063 ret[0] = p->getRed(); 00064 ret[1] = p->getGreen(); 00065 ret[2] = p->getBlue(); 00066 } else { 00067 ret[0] = p->getHue(); 00068 ret[1] = p->getSaturation(); 00069 ret[2] = p->getValue(); 00070 } 00071 return ret; 00072 } 00073 float Color::distance(const Color c)const{ 00074 return p->distance(c.p); 00075 } 00076 bool Color::operator<(const Color rhs)const{ 00077 return p->operator<(rhs); 00078 } 00079 bool Color::operator==(const Color rhs)const{ 00080 return p->operator==(rhs); 00081 } 00082 /// . 00083 /// On a une palette de couleurs pr�d�finie et on retourne 00084 /// cycliquement les couleurs quelles contient. Les valeur de la palettes 00085 /// sont tir�es de la colormap "cool" de Matlab 00086 Color Color::getColor(int i){ 00087 // la palette 00088 const static float palet[64][3] = { 00089 {0,0,143.4375}, {0,0,159.375}, {0,0,175.3125}, {0,0,191.25}, {0,0,207.1875}, 00090 {0,0,223.125},{0,0,239.0625}, {0,0,255}, {0,15.9375,255}, {0,31.875,255}, 00091 {0,47.8125,255}, {0,63.75,255}, {0,79.6875,255}, {0,95.625,255}, {0,111.5625,255}, 00092 {0,127.5,255}, {0,143.4375,255}, {0,159.375,255}, {0,175.3125,255}, {0,191.25,255}, 00093 {0,207.1875,255}, {0,223.125,255}, {0,239.0625,255}, {0,255,255}, {15.9375,255,239.0625}, 00094 {31.875,255,223.125}, {47.8125,255,207.1875}, {63.75,255,191.25}, {79.6875,255,175.3125}, 00095 {95.625,255,159.375}, {111.5625,255,143.4375}, {127.5,255,127.5}, {143.4375,255,111.5625}, 00096 {159.375,255,95.625}, {175.3125,255,79.6875}, {191.25,255,63.75}, {207.1875,255,47.8125}, 00097 {223.125,255,31.875}, {239.0625,255,15.9375}, {255,255,0}, {255,239.0625,0}, {255,223.125,0}, 00098 {255,207.1875,0}, {255,191.25,0}, {255,175.3125,0}, {255,159.375,0}, {255,143.4375,0}, 00099 {255,127.5,0}, {255,111.5625,0}, {255,95.625,0}, {255,79.6875,0}, {255,63.75,0}, {255,47.8125,0}, 00100 {255,31.875,0}, {255,15.9375,0}, {255,0,0}, {239.0625,0,0}, {223.125,0,0}, {207.1875,0,0}, 00101 {191.25,0,0}, {175.3125,0,0}, {159.375,0,0}, {143.4375,0,0},{127.5,0,0} 00102 }; 00103 // indexe dans la palette 00104 int ndx = i % 64 ; 00105 Color ret(palet[ndx][0], palet[ndx][1], palet[ndx][2], true); 00106 return ret; 00107 } 00108 Color Color::getAverageColor(Color color1, int size1, Color color2, int size2){ 00109 int total = size1 + size2; 00110 float h = (size1 * color1.getHue() + size2 * color2.getHue()); 00111 float s = (size1 * color1.getSaturation() + size2 * color2.getSaturation()); 00112 float v = (size1 * color1.getValue() + size2 * color2.getValue()); 00113 h /= total; 00114 s /= total; 00115 v /= total; 00116 Color ret(h, s, v, false); 00117 return ret; 00118 00119 } 00120 bool Color::inWindow(float* color1, float radius, float* color2){ 00121 float deltaV = (color1[2] - color2[2]); 00122 if(deltaV < 0){ 00123 deltaV = -deltaV; 00124 } 00125 if(deltaV > radius){ 00126 return false; 00127 } 00128 float deltaH = (color1[0] - color2[0]); 00129 if(deltaH < 0){ 00130 deltaH = -deltaH; 00131 } 00132 if(deltaH > radius){ 00133 return false; 00134 } 00135 float deltaS = (color1[1] - color2[1]); 00136 if(deltaS < 0){ 00137 deltaS = -deltaS; 00138 } 00139 if(deltaS > radius){ 00140 return false; 00141 } 00142 return true; 00143 } 00144 /////////////////////////////////////////////////////////////////////////////// 00145 /// Classe : Color_Gray 00146 /////////////////////////////////////////////////////////////////////////////// 00147 string Color_Gray::toString() const{ 00148 std::ostringstream o; 00149 o << "GRAY " << gray; 00150 return o.str(); 00151 } 00152 /// . 00153 /// Valeur absolue de la diff�rence des niveaux de gris 00154 float Color_Gray::distance(const Color_Base* c)const{ 00155 if(c->getType() != type){ 00156 throw std::runtime_error(" DISTANCE DE COULEURS DE TYPE DIFFERENT "); 00157 } 00158 float g = ((Color_Gray*)c)->gray; 00159 float g1 = gray; 00160 00161 float ret = g - g1; 00162 00163 if(ret < 0){ 00164 ret = -ret; 00165 } 00166 ret /= 255.0; 00167 return ret; 00168 } 00169 /// . 00170 /// Comparaison avec l'autre niveau de gris 00171 bool Color_Gray::operator<(const Color rhs) const{ 00172 bool ret = (gray < rhs.getGray()); 00173 return ret; 00174 } 00175 /// . 00176 /// Egalit� avec l'autre niveau de gris 00177 bool Color_Gray::operator==(const Color rhs) const{ 00178 bool ret = (gray == rhs.getGray()); 00179 return ret; 00180 } 00181 /////////////////////////////////////////////////////////////////////////////// 00182 /// Classe : Color_Color 00183 /////////////////////////////////////////////////////////////////////////////// 00184 00185 /// . 00186 /// Construit une couleur � partir de 3 valeures flottantes 00187 /// Le param�tre rgb indique si la les composantes sont des valeures RGB ou HSV 00188 /// On calcule imm�diatement la conversion entre RGB et HSV 00189 /// \param f1,f2,f3 les 3 composantes 00190 /// \param rgb indique le type de coordonn�es 00191 Color_Color::Color_Color(float f1, float f2, float f3, bool rgb):Color_Base(COLOR_COLOR){ 00192 if(rgb){ 00193 red = f1; 00194 green = f2; 00195 blue = f3; 00196 // conversion 00197 _computeHSV(); 00198 }else{ 00199 hue = f1; 00200 saturation = f2; 00201 value = f3; 00202 // conversion 00203 _computeRGB(); 00204 } 00205 } 00206 string Color_Color::toString() const{ 00207 std::ostringstream o; 00208 o << "COLOR [" << red << ":" << green << ":" << blue << "][" << hue << ":" << saturation << ":" << value << "]"; 00209 return o.str(); 00210 } 00211 /// . 00212 /// Conversion des coordonn�es cylindriques en coordonn�es 00213 /// cart�siennes et calcule de la norme euclidienne 00214 float Color_Color::distance(const Color_Base* c)const{ 00215 if(c->getType() != type){ 00216 throw std::runtime_error(" DISTANCE DE COULEURS DE TYPE DIFFERENT "); 00217 } 00218 Color_Color* col = (Color_Color*)c; 00219 // coordonn�es cart�siennes de l'instance 00220 float v1 = value * saturation * cos(2 * Pi * hue); 00221 float v2 = value * saturation * sin(2 * Pi * hue); 00222 float v3 = value; 00223 // coordonn�es cart�siennes de l'autre instance 00224 float w1 = (col->value) * (col->saturation) * cos(2 * Pi * (col->hue)); 00225 float w2 = (col->value) * (col->saturation) * sin(2 * Pi * (col->hue)); 00226 float w3 = (col->value); 00227 // norme euclidienne 00228 float hh = v1 - w1; 00229 hh *= hh; 00230 float ss = v2 - w2; 00231 ss *= ss; 00232 float vv = v3 - w3; 00233 vv *= vv; 00234 float ret = sqrt(hh + ss + vv ); 00235 return ret; 00236 00237 } 00238 ///. 00239 /// Conversion RGB->HSV Algorithme tir� de www.easyrgb.com 00240 void Color_Color::_computeHSV(){ 00241 float min, max, delta; 00242 00243 float r = (float)red / 255; 00244 float g = (float)green / 255; 00245 float b = (float)blue / 255; 00246 00247 min = (r < g ? r : g); 00248 min = (b < min ? b : min); 00249 00250 max = (r > g ? r : g); 00251 max = (b > max ? b : max); 00252 00253 delta = max - min; 00254 value = max; 00255 00256 if (delta == 0){ 00257 hue = 0; 00258 saturation = 0; 00259 } else { 00260 saturation = delta / max; 00261 float deltaR = ( ( ( max - r ) / 6 ) + ( delta / 2 ) ) / delta; 00262 float deltaG = ( ( ( max - g ) / 6 ) + ( delta / 2 ) ) / delta; 00263 float deltaB = ( ( ( max - b ) / 6 ) + ( delta / 2 ) ) / delta; 00264 00265 if( r == max ){ 00266 hue = deltaB - deltaG; 00267 }else if( g == max ){ 00268 hue = ( 1.0 / 3.0 ) + deltaR - deltaB; 00269 }else if( b == max ){ 00270 hue = ( 2.0 / 3.0 ) + deltaG - deltaR; 00271 } 00272 00273 if ( hue < 0 ){ 00274 hue += 1; 00275 } 00276 if ( hue > 1 ){ 00277 hue -= 1; 00278 } 00279 } 00280 } 00281 ///. 00282 /// Conversion HSV->RGB Algorithme tir� de www.easyrgb.com 00283 void Color_Color::_computeRGB(){ 00284 if(saturation == 0){ 00285 red = value * 255; 00286 green = value * 255; 00287 blue = value * 255; 00288 }else{ 00289 float var_h = hue * 6; 00290 float var_i = int(var_h); 00291 float var_1 = value * (1 - saturation); 00292 float var_2 = value * (1 - saturation * (var_h -var_i)); 00293 float var_3 = value * (1 - saturation * (1 - (var_h - var_i))); 00294 00295 float var_r = 0.0; 00296 float var_g = 0.0; 00297 float var_b = 0.0; 00298 if(var_i == 0){ 00299 var_r = value; 00300 var_g = var_3; 00301 var_b = var_1; 00302 }else if(var_i == 1){ 00303 var_r = var_2; 00304 var_g = value; 00305 var_b = var_1; 00306 }else if(var_i == 2){ 00307 var_r = var_1; 00308 var_g = value; 00309 var_b = var_3; 00310 }else if(var_i == 3){ 00311 var_r = var_1; 00312 var_g = var_2; 00313 var_b = value; 00314 }else if(var_i == 4){ 00315 var_r = var_3; 00316 var_g = var_1; 00317 var_b = value; 00318 }else{ 00319 var_r = value; 00320 var_g = var_1; 00321 var_b = var_2; 00322 } 00323 red = var_r * 255; 00324 green = var_g * 255; 00325 blue = var_b * 255; 00326 } 00327 } 00328 /// . 00329 /// L'odre utilis� est l'ordre lexicographique : on compare les 00330 /// composantes HSV des 2 couleurs 00331 bool Color_Color::operator<(const Color rhs) const{ 00332 // composante H 00333 float h = hue - rhs.getHue(); 00334 if(h < 0){ 00335 return true; 00336 } 00337 // si les composantes H sont �gales, on test S 00338 float s = saturation - rhs.getSaturation(); 00339 if(h == 0 && s < 0){ 00340 return true; 00341 } 00342 // si les composantes H et S sont �gales, on test V 00343 float v = value - rhs.getValue(); 00344 if(h == 0 && s == 0 && v < 0 ){ 00345 return true; 00346 } 00347 // sinon l'autre couleur est plus grande 00348 return false; 00349 } 00350 /// . 00351 /// L'odre utilis� est l'ordre lexicographique : on compare les 00352 /// composantes HSV des 2 couleurs 00353 bool Color_Color::operator==(const Color rhs) const{ 00354 bool ret = true; 00355 00356 ret &= (hue == rhs.getHue()); 00357 ret &= (saturation == rhs.getSaturation()); 00358 ret &= (value == rhs.getValue()); 00359 00360 return ret; 00361 }

G�n�r� le Thu Jul 1 23:13:32 2004 pour segment par doxygen 1.3.7