00001
00002
00003
#include "Color.hpp"
00004
00005
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
00084
00085
00086 Color Color::getColor(
int i){
00087
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
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
00146
00147 string
Color_Gray::toString()
const{
00148 std::ostringstream o;
00149 o <<
"GRAY " <<
gray;
00150
return o.str();
00151 }
00152
00153
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
00171 bool Color_Gray::operator<(
const Color rhs)
const{
00172
bool ret = (
gray < rhs.
getGray());
00173
return ret;
00174 }
00175
00176
00177 bool Color_Gray::operator==(
const Color rhs)
const{
00178
bool ret = (
gray == rhs.
getGray());
00179
return ret;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
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
00197
_computeHSV();
00198 }
else{
00199
hue = f1;
00200
saturation = f2;
00201
value = f3;
00202
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
00213
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
00220
float v1 = value * saturation * cos(2 *
Pi * hue);
00221
float v2 = value * saturation * sin(2 *
Pi * hue);
00222
float v3 = value;
00223
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
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
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
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
00330
00331 bool Color_Color::operator<(
const Color rhs)
const{
00332
00333
float h =
hue - rhs.
getHue();
00334
if(h < 0){
00335
return true;
00336 }
00337
00338
float s =
saturation - rhs.
getSaturation();
00339
if(h == 0 && s < 0){
00340
return true;
00341 }
00342
00343
float v =
value - rhs.
getValue();
00344
if(h == 0 && s == 0 && v < 0 ){
00345
return true;
00346 }
00347
00348
return false;
00349 }
00350
00351
00352
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 }