File indexing completed on 2024-12-22 04:17:51

0001 /***************************************************************************
0002  *                                                                         *
0003  *   copyright : (C) 2003 The University of Toronto                        *
0004  *                   netterfield@astro.utoronto.ca                         *
0005  *                                                                         *
0006  *   This program is free software; you can redistribute it and/or modify  *
0007  *   it under the terms of the GNU General Public License as published by  *
0008  *   the Free Software Foundation; either version 2 of the License, or     *
0009  *   (at your option) any later version.                                   *
0010  *                                                                         *
0011  ***************************************************************************/
0012 
0013 // delivers new colors...
0014 //
0015 
0016 // application specific includes
0017 #include "colorsequence.h"
0018 #include <QVector>
0019 #include <qapplication.h>
0020 #include <math_kst.h>
0021 
0022 namespace Kst {
0023 
0024 static const QLatin1String& KstColorSequenceName = QLatin1String("KstColors");
0025 
0026 
0027 ColorSequence *ColorSequence::_self = &ColorSequence::self();
0028 
0029 
0030 ColorSequence& ColorSequence::self() {
0031   if (!_self) {
0032     _self = new ColorSequence;
0033     qAddPostRoutine(ColorSequence::cleanup);
0034   }
0035   return *_self;
0036 }
0037 
0038 
0039 void ColorSequence::cleanup() {
0040     delete _self;
0041     _self = 0;
0042 }
0043 
0044 
0045 ColorSequence::ColorSequence() {
0046   _colors.append(QColor::fromRgb(209,   0,   0));
0047   _colors.append(QColor::fromRgb(  0, 166, 255));
0048   _colors.append(QColor::fromRgb( 95, 154,   0));
0049   _colors.append(QColor::fromRgb(178,  24, 255));
0050   _colors.append(QColor::fromRgb(255, 200,   0));
0051   _colors.append(QColor::fromRgb(172, 172, 172));
0052   _colors.append(QColor::fromRgb( 89, 220, 205));
0053   _colors.append(QColor::fromRgb(255, 142, 240));
0054   _colors.append(QColor::fromRgb(130, 123,   0));
0055   _colors.append(QColor::fromRgb(  0,   0, 255));
0056   _colors.append(QColor::fromRgb(202, 116,  29));
0057   _colors.append(QColor::fromRgb( 90,   0,   0));
0058   _colors.append(QColor::fromRgb(  0,  68,   0));
0059 
0060   _count = _colors.size();
0061   _ptr = 0;
0062   _offset = 0;
0063 
0064 }
0065 
0066 ColorSequence::~ColorSequence() {
0067 }
0068 
0069 
0070 QColor ColorSequence::next() {
0071   incIndex();
0072   return entry(_ptr);
0073 }
0074 
0075 
0076 QColor ColorSequence::current() {
0077   return entry(_ptr);
0078 }
0079 
0080 QColor ColorSequence::entry(int i) {
0081   // makes sure 0<=i<count.
0082   i = abs(i+_offset)%_count;
0083 
0084   return _colors.at(i);
0085 }
0086 
0087 
0088 //QColor ColorSequence::next_c_bc(const CurveList& curves, const QColor& badColor) {
0089 //  QColor color;
0090 //  int dark_factor;
0091 //  int ptrMin;
0092 //  int start;
0093 
0094 //  createPalette();
0095 
0096 //  QVector<int> usage(_count*2);
0097 
0098 //  for (int i = 0; i < _count*2; i++) {
0099 //    usage[i] = 0;
0100 //  }
0101 
0102 //  // check we are not already using this color, but if
0103 //  //  we are then count the number of usages of each color
0104 //  //  in the palette.
0105 //  start = _ptr;
0106 //  if (start >= _count * 2) {
0107 //    start = 0;
0108 //  }
0109 
0110 //  while (_ptr != start) {
0111 //    if (_ptr >= _count * 2) {
0112 //      _ptr = 0;
0113 //    }
0114 
0115 //    dark_factor = 100 + ( 50 * ( _ptr / _count ) );
0116 //    color = _pal.value( _ptr % _count).dark(dark_factor);
0117 
0118 //    // if we are too close to the bad color then increase the usage count
0119 //    //  to try and not use it.
0120 //    if (badColor.isValid() && colorsTooClose(color, badColor) ) {
0121 //      usage[_ptr] += 100;
0122 //    }
0123 
0124 //    for (int i = 0; i < (int)curves.count(); i++) {
0125 //      if (color == curves[i]->color()) {
0126 //        usage[_ptr]++;
0127 //      }
0128 //    }
0129 
0130 //    if (usage[_ptr] == 0) {
0131 //      break;
0132 //    }
0133 
0134 //    _ptr++;
0135 //  }
0136 
0137 //  // if we are already using this color then use the least used color for all the curves.
0138 //  if (usage[_ptr] != 0) {
0139 //    ptrMin = _ptr;
0140 
0141 //    while (_ptr != start) {
0142 //      if (_ptr >= _count * 2) {
0143 //        _ptr = 0;
0144 //      }
0145 
0146 //      if (usage[_ptr] < usage[ptrMin]) {
0147 //        ptrMin = _ptr;
0148 //      }
0149 
0150 //      _ptr++;
0151 //    }
0152 
0153 //    _ptr = ptrMin;
0154 //  }
0155 
0156 //  dark_factor = 100 + ( 50 * ( _ptr / _count ) );
0157 //  color = _pal.value( _ptr++ % _count).dark(dark_factor);
0158 
0159 //  return color;
0160 //}
0161 
0162 
0163 //QColor ColorSequence::next_bc(const QColor& badColor) {
0164 //  QColor color;
0165 //  int dark_factor;
0166 
0167 //  createPalette();
0168 
0169 //  int start = _ptr;
0170 
0171 //  // find the next color in the sequence that it not too close to the bad color.
0172 //  if (badColor.isValid()) {
0173 //    do {
0174 //      if (_ptr >= _count * 2) {
0175 //        _ptr = 0;
0176 //      }
0177 //      dark_factor = 100 + ( 50 * ( _ptr / _count ) );
0178 //      color = _pal.value( _ptr++ % _count).dark(dark_factor);
0179 //    } while (colorsTooClose(color, badColor) && start != _ptr);
0180 //  }
0181 
0182 //  // if we couldn't find one then just use the next color in the sequence.
0183 //  if (start == _ptr) {
0184 //    if (_ptr >= _count * 2) {
0185 //      _ptr = 0;
0186 //    }
0187 //    dark_factor = 100 + ( 50 * ( _ptr / _count ) );
0188 //    color = _pal.value( _ptr++ % _count).dark(dark_factor);
0189 //  }
0190 
0191 //  return color;
0192 //}
0193 
0194 
0195 //bool ColorSequence::colorsTooClose(const QColor& color, const QColor& badColor) {
0196 //  double r1, h1, f1, x1, y1, z1;
0197 //  double r2, h2, f2, x2, y2, z2;
0198 //  double dc;
0199 //  int sugH, sugS, sugV;
0200 //  int badH, badS, badV;
0201 
0202 //  // make sure that the new color is not close to badColor.
0203 //  // to do this imagine HSV as defining a cone.
0204 //  // The distance from the point of the cone is R = V / 255
0205 //  // Angle of rotational symetry is Theta = H * 2PI/360
0206 //  // The 2nd angle is phi = S*(PI/4)/255
0207 //  // a color is acceptable if |C1-C2|>dcMin
0208 
0209 //  color.getHsv(&sugH,&sugS,&sugV);
0210 //  badColor.getHsv(&badH, &badS, &badV);
0211 
0212 //  r1 = badV/255.0;
0213 //  h1 = badH*M_PI/180.0;
0214 //  f1 = badS*M_PI/4.0/255.0;
0215 //  x1 = r1*sin( h1 )*sin( f1 );
0216 //  y1 = r1*cos( h1 )*sin( f1 );
0217 //  z1 = r1*cos( f1 );
0218 //  r2 = sugV/255.0;
0219 //  h2 = sugH*M_PI/180.0;
0220 //  f2 = sugS*M_PI/4.0/255.0;
0221 //  x2 = r2*sin( h2 )*sin( f2 );
0222 //  y2 = r2*cos( h2 )*sin( f2 );
0223 //  z2 = r2*cos( f2 );
0224 //  dc = sqrt( ( x1-x2 )*( x1-x2 ) + ( y1-y2 )*( y1-y2 ) + ( z1-z2 )*( z1-z2 ) );
0225 
0226 //  return dc < 0.3;
0227 //}
0228 
0229 
0230 //ColorSequence::ColorMode ColorSequence::colorMode() {
0231 //  return _mode;
0232 //}
0233 
0234 
0235 //void ColorSequence::setColorMode(ColorSequence::ColorMode mode) {
0236 //  _mode = mode;
0237 //}
0238 
0239 
0240 //int ColorSequence::count() {
0241 //  createPalette();
0242 
0243 //  return _count * 2;
0244 //}
0245 
0246 
0247 //void ColorSequence::reset() {
0248 //  _ptr = 0;
0249 //}
0250 
0251 
0252 }
0253 // vim: ts=2 sw=2 et