2532

Dependencies:   QEI WS2812 PixelArray DFPlayerMini MODSERIAL PCA9685_ pca9685

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rgbhsv.h Source File

rgbhsv.h

00001 typedef struct {
00002     double r;       // a fraction between 0 and 1
00003     double g;       // a fraction between 0 and 1
00004     double b;       // a fraction between 0 and 1
00005 } rgb;
00006 
00007 typedef struct {
00008     double h;       // angle in degrees
00009     double s;       // a fraction between 0 and 1
00010     double v;       // a fraction between 0 and 1
00011 } hsv;
00012 
00013 hsv   rgb2hsv(rgb in);
00014 rgb   hsv2rgb(hsv in);
00015 
00016 hsv rgb2hsv(rgb in)
00017 {
00018     hsv         out;
00019     double      min, max, delta;
00020 
00021     min = in.r < in.g ? in.r : in.g;
00022     min = min  < in.b ? min  : in.b;
00023 
00024     max = in.r > in.g ? in.r : in.g;
00025     max = max  > in.b ? max  : in.b;
00026 
00027     out.v = max;                                // v
00028     delta = max - min;
00029     if (delta < 0.00001)
00030     {
00031         out.s = 0;
00032         out.h = 0; // undefined, maybe nan?
00033         return out;
00034     }
00035     if( max > 0.0 ) { // NOTE: if Max is == 0, this divide would cause a crash
00036         out.s = (delta / max);                  // s
00037     } else {
00038         // if max is 0, then r = g = b = 0              
00039         // s = 0, h is undefined
00040         out.s = 0.0;
00041         out.h = NAN;                            // its now undefined
00042         return out;
00043     }
00044     if( in.r >= max )                           // > is bogus, just keeps compilor happy
00045         out.h = ( in.g - in.b ) / delta;        // between yellow & magenta
00046     else
00047     if( in.g >= max )
00048         out.h = 2.0 + ( in.b - in.r ) / delta;  // between cyan & yellow
00049     else
00050         out.h = 4.0 + ( in.r - in.g ) / delta;  // between magenta & cyan
00051 
00052     out.h *= 60.0;                              // degrees
00053 
00054     if( out.h < 0.0 )
00055         out.h += 360.0;
00056 
00057     return out;
00058 }
00059 
00060 
00061 rgb hsv2rgb(hsv in)
00062 {
00063     double      hh, p, q, t, ff;
00064     long        i;
00065     rgb         out;
00066 
00067     if(in.s <= 0.0) {       // < is bogus, just shuts up warnings
00068         out.r = in.v;
00069         out.g = in.v;
00070         out.b = in.v;
00071         return out;
00072     }
00073     hh = in.h;
00074     if(hh >= 360.0) hh = 0.0;
00075     hh /= 60.0;
00076     i = (long)hh;
00077     ff = hh - i;
00078     p = in.v * (1.0 - in.s);
00079     q = in.v * (1.0 - (in.s * ff));
00080     t = in.v * (1.0 - (in.s * (1.0 - ff)));
00081 
00082     switch(i) {
00083     case 0:
00084         out.r = in.v;
00085         out.g = t;
00086         out.b = p;
00087         break;
00088     case 1:
00089         out.r = q;
00090         out.g = in.v;
00091         out.b = p;
00092         break;
00093     case 2:
00094         out.r = p;
00095         out.g = in.v;
00096         out.b = t;
00097         break;
00098 
00099     case 3:
00100         out.r = p;
00101         out.g = q;
00102         out.b = in.v;
00103         break;
00104     case 4:
00105         out.r = t;
00106         out.g = p;
00107         out.b = in.v;
00108         break;
00109     case 5:
00110     default:
00111         out.r = in.v;
00112         out.g = p;
00113         out.b = q;
00114         break;
00115     }
00116     return out;     
00117 }