1 #include "igs_color_rgb_hsv.h"
rgb_to_hsv(const double red,const double gre,const double blu,double & hue,double & sat,double & val)2 void igs::color::rgb_to_hsv(const double red,  // 0.0...1.0
3                             const double gre,  // 0.0...1.0
4                             const double blu,  // 0.0...1.0
5                             double &hue,       /* 0.0...360.0	hue(色相) */
6                             double &sat, /* 0.0...1.0	saturation(彩度) */
7                             double &val  /* 0.0...1.0	value(明度) */
8                             ) {
9   const double maxi =
10       (red < gre) ? ((gre < blu) ? blu : gre) : ((red < blu) ? blu : red);
11   const double mini =
12       (gre < red) ? ((blu < gre) ? blu : gre) : ((blu < red) ? blu : red);
13 
14   val = maxi; /* value(明度) */
15 
16   if (maxi == mini) { /* RGB各色に差がない(白黒の)とき */
17     sat = 0.0;        /* saturation(彩度)はゼロ */
18     hue = 0.0;        /* hue(色相)は意味を持たない */
19   } else {            /* 色のあるとき */
20     sat = (maxi - mini) / maxi;
21 
22     const double maxmin = maxi - mini;
23 
24     /* -1 .. 1 マゼンタ(M)から黄色(Y)までの間の色 */
25     if (red == maxi) {
26       hue = (gre - blu) / maxmin;
27     }
28 
29     /*  1 .. 3 黄色(Y)からシアン(C)までの間の色 */
30     else if (gre == maxi) {
31       hue = 2.0 + (blu - red) / maxmin;
32     }
33 
34     /*  3 .. 5 シアン(C)からマゼンタ(M)までの間の色 */
35     else if (blu == maxi) {
36       hue = 4.0 + (red - gre) / maxmin;
37     }
38     /*
39             M-R-Y-G-C-B-M
40            -1 0 1 2 3 4 5
41     */
42     hue *= 60.0; /* -60 ... 300 */
43     if (hue < 0.0) {
44       hue += 360.0;
45     }
46   }
47 }
48 #include <cmath> /* floor() */
hsv_to_rgb(const double hue,const double sat,const double val,double & red,double & gre,double & blu)49 void igs::color::hsv_to_rgb(
50     const double hue, /* 0.0...360.0	hue(色相) */
51     const double sat, /* 0.0...1.0	saturation(彩度) */
52     const double val, /* 0.0...1.0	value(明度) */
53     double &red,      /* 0.0...1.0 */
54     double &gre,      /* 0.0...1.0 */
55     double &blu       /* 0.0...1.0 */
56     ) {
57   if (0.0 == sat) { /* 白黒で色がない */
58     red = gre = blu = val;
59   } else { /* 色のあるとき */
60     double hh = hue;
61     while (360.0 <= hh) {
62       hh -= 360.0;
63     }
64     hh /= 60.0; /* 0〜359.999... --> 0〜5.999... */
65 
66     const double ii = floor(hh); /* 最大整数値 */
67     const double ff = hh - ii;   /* hueの小数部 */
68     const double pp = val * (1.0 - sat);
69     const double qq = val * (1.0 - (sat * ff));
70     const double tt = val * (1.0 - (sat * (1.0 - ff)));
71 
72     switch (static_cast<int>(ii)) {
73     case 0:
74       red = val;
75       gre = tt;
76       blu = pp;
77       break;
78     case 1:
79       red = qq;
80       gre = val;
81       blu = pp;
82       break;
83     case 2:
84       red = pp;
85       gre = val;
86       blu = tt;
87       break;
88     case 3:
89       red = pp;
90       gre = qq;
91       blu = val;
92       break;
93     case 4:
94       red = tt;
95       gre = pp;
96       blu = val;
97       break;
98     case 5:
99       red = val;
100       gre = pp;
101       blu = qq;
102       break;
103     }
104   }
105 }
106