Toshihiro Shimizu 890ddd
#include "igs_color_rgb_hsv.h"
shun-iwasawa 481b59
#include <cmath></cmath>
Shinya Kitaoka 120a6e
void igs::color::rgb_to_hsv(const double red,  // 0.0...1.0
Shinya Kitaoka 120a6e
                            const double gre,  // 0.0...1.0
Shinya Kitaoka 120a6e
                            const double blu,  // 0.0...1.0
Shinya Kitaoka 120a6e
                            double &hue,       /* 0.0...360.0	hue(色相) */
Shinya Kitaoka 120a6e
                            double &sat, /* 0.0...1.0	saturation(彩度) */
Shinya Kitaoka 120a6e
                            double &val  /* 0.0...1.0	value(明度) */
shun-iwasawa 481b59
) {
Shinya Kitaoka 120a6e
  const double maxi =
Shinya Kitaoka 120a6e
      (red < gre) ? ((gre < blu) ? blu : gre) : ((red < blu) ? blu : red);
Shinya Kitaoka 120a6e
  const double mini =
Shinya Kitaoka 120a6e
      (gre < red) ? ((blu < gre) ? blu : gre) : ((blu < red) ? blu : red);
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
  bool invertValue = std::abs(mini) > std::abs(maxi);
shun-iwasawa 481b59
shun-iwasawa 481b59
  val = (invertValue) ? mini : maxi; /* value(明度) */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (maxi == mini) { /* RGB各色に差がない(白黒の)とき */
Shinya Kitaoka 120a6e
    sat = 0.0;        /* saturation(彩度)はゼロ */
Shinya Kitaoka 120a6e
    hue = 0.0;        /* hue(色相)は意味を持たない */
Shinya Kitaoka 120a6e
  } else {            /* 色のあるとき */
shun-iwasawa 481b59
    sat = (invertValue) ? (mini - maxi) / mini : (maxi - mini) / maxi;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    const double maxmin = maxi - mini;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    /* -1 .. 1 マゼンタ(M)から黄色(Y)までの間の色 */
Shinya Kitaoka 120a6e
    if (red == maxi) {
Shinya Kitaoka 120a6e
      hue = (gre - blu) / maxmin;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    /*  1 .. 3 黄色(Y)からシアン(C)までの間の色 */
Shinya Kitaoka 120a6e
    else if (gre == maxi) {
Shinya Kitaoka 120a6e
      hue = 2.0 + (blu - red) / maxmin;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    /*  3 .. 5 シアン(C)からマゼンタ(M)までの間の色 */
Shinya Kitaoka 120a6e
    else if (blu == maxi) {
Shinya Kitaoka 120a6e
      hue = 4.0 + (red - gre) / maxmin;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    /*
Shinya Kitaoka 120a6e
            M-R-Y-G-C-B-M
Shinya Kitaoka 120a6e
           -1 0 1 2 3 4 5
Shinya Kitaoka 120a6e
    */
Shinya Kitaoka 120a6e
    hue *= 60.0; /* -60 ... 300 */
shun-iwasawa 481b59
    if (invertValue) hue -= 180.0;
Shinya Kitaoka 120a6e
    if (hue < 0.0) {
Shinya Kitaoka 120a6e
      hue += 360.0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
shun-iwasawa 481b59
#include <cmath>                              /* floor() */</cmath>
shun-iwasawa 481b59
void igs::color::hsv_to_rgb(const double hue, /* 0.0...360.0	hue(色相) */
shun-iwasawa 481b59
                            const double sat, /* 0.0...1.0 saturation(彩度) */
shun-iwasawa 481b59
                            const double val, /* 0.0...1.0	value(明度) */
shun-iwasawa 481b59
                            double &red,      /* 0.0...1.0 */
shun-iwasawa 481b59
                            double &gre,      /* 0.0...1.0 */
shun-iwasawa 481b59
                            double &blu       /* 0.0...1.0 */
shun-iwasawa 481b59
) {
Shinya Kitaoka 120a6e
  if (0.0 == sat) { /* 白黒で色がない */
Shinya Kitaoka 120a6e
    red = gre = blu = val;
Shinya Kitaoka 120a6e
  } else { /* 色のあるとき */
Shinya Kitaoka 120a6e
    double hh = hue;
Shinya Kitaoka 120a6e
    while (360.0 <= hh) {
Shinya Kitaoka 120a6e
      hh -= 360.0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    hh /= 60.0; /* 0〜359.999... --> 0〜5.999... */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    const double ii = floor(hh); /* 最大整数値 */
Shinya Kitaoka 120a6e
    const double ff = hh - ii;   /* hueの小数部 */
Shinya Kitaoka 120a6e
    const double pp = val * (1.0 - sat);
Shinya Kitaoka 120a6e
    const double qq = val * (1.0 - (sat * ff));
Shinya Kitaoka 120a6e
    const double tt = val * (1.0 - (sat * (1.0 - ff)));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    switch (static_cast<int>(ii)) {</int>
Shinya Kitaoka 120a6e
    case 0:
Shinya Kitaoka 120a6e
      red = val;
Shinya Kitaoka 120a6e
      gre = tt;
Shinya Kitaoka 120a6e
      blu = pp;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case 1:
Shinya Kitaoka 120a6e
      red = qq;
Shinya Kitaoka 120a6e
      gre = val;
Shinya Kitaoka 120a6e
      blu = pp;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case 2:
Shinya Kitaoka 120a6e
      red = pp;
Shinya Kitaoka 120a6e
      gre = val;
Shinya Kitaoka 120a6e
      blu = tt;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case 3:
Shinya Kitaoka 120a6e
      red = pp;
Shinya Kitaoka 120a6e
      gre = qq;
Shinya Kitaoka 120a6e
      blu = val;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case 4:
Shinya Kitaoka 120a6e
      red = tt;
Shinya Kitaoka 120a6e
      gre = pp;
Shinya Kitaoka 120a6e
      blu = val;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case 5:
Shinya Kitaoka 120a6e
      red = val;
Shinya Kitaoka 120a6e
      gre = pp;
Shinya Kitaoka 120a6e
      blu = qq;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}