Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Examples  

RGB.H

Go to the documentation of this file.
00001 
00015 #ifndef RGB_H
00016 #define RGB_H
00017 
00018 #include <Vector.H>
00019 #include <color.H>
00020 
00021 namespace xchen
00022 {
00023   typedef fVector3D RGB;
00024   typedef fVector3D HSV;
00025   typedef fVector4D RGBA;
00026   typedef fVector4D RGBI;
00027   typedef fVector5D RGBAS;
00028   
00029   inline void RGBOverFlowByScale(fVector3D& rgb)
00030   {
00031     float max = * (max_element(rgb.begin(), rgb.end()));
00032     if(max<=1.0) rgb /= max;   
00033   }
00034   inline void RGBOverFlowByClamp(fVector3D& rgb)
00035   {
00036     for(int i=0; i<3; i++) if(rgb[i]>1.0) rgb[i] = 1.0; 
00037   }
00038   inline void RGBOverFlowByMark(fVector3D& rgb)
00039   {
00040     float max = * (max_element(rgb.begin(), rgb.end()));
00041     if(max<=1.0) rgb = Firebrick;
00042   }
00043 
00044   inline bool RGBASisOpaque(const RGBAS& rgbas)
00045   {
00046     return  approx_eq(1.0, rgbas[3]);
00047   }
00048   
00049 
00050   /* 
00051    *HSV hexcone and RGB cube is actually affine transform(if we lift white pnt in hexcone a bit),
00052    * and this is why H is not angle, but a ratio pnt at each edge.
00053    *
00054    * hs-hexogon consists of three regions (three outer cube face) 
00055    */
00056   enum RGBCubeFace { WhiteRedFace, WhiteGreenFace, WhiteBlueFace };
00057   inline void HSV2RGB(fVector3D& hsv)
00058   {
00059     const float H = hsv[0], S = hsv[1], V = hsv[2];
00060 
00061     int f = (int ((H+1.0) / 2.0));
00062     if(f>2) f--;
00063     RGBCubeFace face = (RGBCubeFace) f;
00064 
00065     float HH = H - 2.0 * face;
00066     if(HH>1.0) HH -= 2.0;
00067 
00068     float c[3]; c[0] = V;
00069     if(HH>=0) {
00070       c[1] = (1-(1-HH)*S) * V;
00071       c[2] = (1.0-S) * V;
00072     }
00073     else {
00074       c[2] = (1-(1+HH)*S) * V;
00075       c[1] = (1.0-S) * V;
00076     }
00077     copy(c, c+3, hsv.begin());
00078   }
00079   inline void RGB2HSV(fVector3D& rgb)
00080   {
00081     fVector3D::iterator itr = max_element(rgb.begin(), rgb.end());
00082     RGBCubeFace face = (RGBCubeFace) distance(rgb.begin(), itr); //(RGBCubeFace) _max_index(rgb.r(), rgb.g(), rgb.b());
00083   
00084     float H, S, V = *itr;
00085     if(!V) {
00086       fill(rgb.begin(), rgb.end(), 0.0);
00087       return;
00088     }
00089 
00090     if(++itr == rgb.end())
00091       itr = rgb.begin();
00092     float c1 = (*itr) / V;
00093 
00094     if(++itr == rgb.end())
00095       itr = rgb.begin();
00096     float c2 = (*itr) / V;
00097 
00098     if(c1 > c2) {
00099       S = 1.0 - c2;
00100       H = S? (1.0 -(1.0-c1) / S) + face * 2.0 : 0.0;
00101     }
00102     else {
00103       S = 1.0 - c1;
00104       H = S? (1.0-c2) / S - 1.0 + face * 2.0 : 0.0;
00105       if(H<0) H += 6.0;
00106     }
00107     rgb[0] = H, rgb[1] = S, rgb[2] = V;
00108   }
00109 }
00110 #endif
00111 

Generated on Wed Apr 7 21:40:49 2004 by doxygen1.2.18