Toshihiro Shimizu 890ddd
#include "igs_color_rgb_hls.h"
Shinya Kitaoka 120a6e
void igs::color::rgb_to_hls(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 &lig,       /* 0.0...1.0	lightness(明度) */
shun-iwasawa 481b59
                            double &sat,      /* 0.0...1.0	saturation(彩度) */
shun-iwasawa 481b59
                            bool cylindrical  // either cylindrical or conical
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
Shinya Kitaoka 120a6e
  lig = (maxi + mini) / 2.0;
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
    if (cylindrical) {
shun-iwasawa 481b59
      if (lig <= 0.5) {
shun-iwasawa 481b59
        sat = (maxi - mini) / (maxi + mini);
shun-iwasawa 481b59
      } else {
shun-iwasawa 481b59
        sat = (maxi - mini) / (2.0 - (maxi + mini));
shun-iwasawa 481b59
      }
shun-iwasawa 481b59
    } else
shun-iwasawa 481b59
      sat = maxi - mini;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    /* 色相(Hue) */
Shinya Kitaoka 120a6e
    const double rmid = (maxi - red) / (maxi - mini);
Shinya Kitaoka 120a6e
    const double gmid = (maxi - gre) / (maxi - mini);
Shinya Kitaoka 120a6e
    const double bmid = (maxi - blu) / (maxi - mini);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    /* -1 .. 1 マゼンタ(M)から黄色(Y)までの間の色 */
Shinya Kitaoka 120a6e
    if (red == maxi) {
Shinya Kitaoka 120a6e
      hue = bmid - gmid;
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 + rmid - bmid;
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 + gmid - rmid;
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 */
Shinya Kitaoka 120a6e
    if (hue < 0.0) {
Shinya Kitaoka 120a6e
      hue += 360.0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
double hls2rgb_calc(const double m1, const double m2, const double hue) {
Shinya Kitaoka 120a6e
  double hh = hue;
Shinya Kitaoka 120a6e
  while (360.0 < hh) {
Shinya Kitaoka 120a6e
    hh -= 360;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  while (hh < 0.0) {
Shinya Kitaoka 120a6e
    hh += 360;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (hh < 60.0) {
Shinya Kitaoka 120a6e
    return m1 + (m2 - m1) * hh / 60.0;
Shinya Kitaoka 120a6e
  } else if (hh < 180.0) {
Shinya Kitaoka 120a6e
    return m2;
Shinya Kitaoka 120a6e
  } else if (hh < 240.0) {
Shinya Kitaoka 120a6e
    return m1 + (m2 - m1) * (240.0 - hh) / 60.0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return m1; /* 240 ... 360 */
Toshihiro Shimizu 890ddd
}
shun-iwasawa 481b59
}  // namespace
shun-iwasawa 481b59
void igs::color::hls_to_rgb(const double hue, /* 0.0...360.0	hue(色相) */
shun-iwasawa 481b59
                            const double lig, /* 0.0...1.0 lightness(明度) */
shun-iwasawa 481b59
                            const double sat, /* 0.0...1.0 saturation(彩度) */
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
                            bool cylindrical  // either cylindrical or conical
shun-iwasawa 481b59
) {
Shinya Kitaoka 120a6e
  if (0.0 == sat) { /* 白黒で色がない */
Shinya Kitaoka 120a6e
    red = gre = blu = lig;
Shinya Kitaoka 120a6e
  } else { /* 色のあるとき */
shun-iwasawa 481b59
    double m2, m1;
shun-iwasawa 481b59
    if (cylindrical) {
shun-iwasawa 481b59
      m2 = (lig <= 0.5) ? (lig * (1.0 + sat)) : (lig + sat - lig * sat);
shun-iwasawa 481b59
      m1 = 2.0 * lig - m2;
shun-iwasawa 481b59
    } else {
shun-iwasawa 481b59
      m2 = lig + sat * 0.5;
shun-iwasawa 481b59
      m1 = lig - sat * 0.5;
shun-iwasawa 481b59
    }
shun-iwasawa 481b59
    red = hls2rgb_calc(m1, m2, hue + 120.0);
shun-iwasawa 481b59
    gre = hls2rgb_calc(m1, m2, hue);
shun-iwasawa 481b59
    blu = hls2rgb_calc(m1, m2, hue - 120.0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}