00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "ColourMapper.h"
00017
00018 #include <iostream>
00019
00020 #include <cmath>
00021
00022 ColourMapper::ColourMapper(int map, float min, float max) :
00023 QObject(),
00024 m_map(map),
00025 m_min(min),
00026 m_max(max)
00027 {
00028 if (m_min == m_max) {
00029 std::cerr << "WARNING: ColourMapper: min == max (== " << m_min
00030 << "), adjusting" << std::endl;
00031 m_max = m_min + 1;
00032 }
00033 }
00034
00035 ColourMapper::~ColourMapper()
00036 {
00037 }
00038
00039 int
00040 ColourMapper::getColourMapCount()
00041 {
00042 return 11;
00043 }
00044
00045 QString
00046 ColourMapper::getColourMapName(int n)
00047 {
00048 if (n >= getColourMapCount()) return tr("<unknown>");
00049 StandardMap map = (StandardMap)n;
00050
00051 switch (map) {
00052 case DefaultColours: return tr("Default");
00053 case WhiteOnBlack: return tr("White on Black");
00054 case BlackOnWhite: return tr("Black on White");
00055 case RedOnBlue: return tr("Red on Blue");
00056 case YellowOnBlack: return tr("Yellow on Black");
00057 case BlueOnBlack: return tr("Blue on Black");
00058 case Sunset: return tr("Sunset");
00059 case FruitSalad: return tr("Fruit Salad");
00060 case Banded: return tr("Banded");
00061 case Highlight: return tr("Highlight");
00062 case Printer: return tr("Printer");
00063 }
00064
00065 return tr("<unknown>");
00066 }
00067
00068 QColor
00069 ColourMapper::map(float value) const
00070 {
00071 float norm = (value - m_min) / (m_max - m_min);
00072 if (norm < 0.f) norm = 0.f;
00073 if (norm > 1.f) norm = 1.f;
00074
00075 float h = 0.f, s = 0.f, v = 0.f, r = 0.f, g = 0.f, b = 0.f;
00076 bool hsv = true;
00077
00078
00079 float blue = 0.6666f, pieslice = 0.3333f;
00080
00081 if (m_map >= getColourMapCount()) return Qt::black;
00082 StandardMap map = (StandardMap)m_map;
00083
00084 switch (map) {
00085
00086 case DefaultColours:
00087 h = blue - norm * 2.f * pieslice;
00088 s = 0.5f + norm/2.f;
00089 v = norm;
00090 break;
00091
00092 case WhiteOnBlack:
00093 r = g = b = norm;
00094 hsv = false;
00095 break;
00096
00097 case BlackOnWhite:
00098 r = g = b = 1.f - norm;
00099 hsv = false;
00100 break;
00101
00102 case RedOnBlue:
00103 h = blue - pieslice/4.f + norm * (pieslice + pieslice/4.f);
00104 s = 1.f;
00105 v = norm;
00106 break;
00107
00108 case YellowOnBlack:
00109 h = 0.15f;
00110 s = 1.f;
00111 v = norm;
00112 break;
00113
00114 case BlueOnBlack:
00115 h = blue;
00116 s = 1.f;
00117 v = norm * 2.f;
00118 if (v > 1.f) {
00119 v = 1.f;
00120 s = 1.f - (sqrtf(norm) - 0.707f) * 3.413f;
00121 if (s < 0.f) s = 0.f;
00122 if (s > 1.f) s = 1.f;
00123 }
00124 break;
00125
00126 case Sunset:
00127 r = (norm - 0.24f) * 2.38f;
00128 if (r > 1.f) r = 1.f;
00129 if (r < 0.f) r = 0.f;
00130 g = (norm - 0.64f) * 2.777f;
00131 if (g > 1.f) g = 1.f;
00132 if (g < 0.f) g = 0.f;
00133 b = (3.6f * norm);
00134 if (norm > 0.277f) b = 2.f - b;
00135 if (b > 1.f) b = 1.f;
00136 if (b < 0.f) b = 0.f;
00137 hsv = false;
00138 break;
00139
00140 case FruitSalad:
00141 h = blue + (pieslice/6.f) - norm;
00142 if (h < 0.f) h += 1.f;
00143 s = 1.f;
00144 v = 1.f;
00145 break;
00146
00147 case Banded:
00148 if (norm < 0.125) return Qt::darkGreen;
00149 else if (norm < 0.25) return Qt::green;
00150 else if (norm < 0.375) return Qt::darkBlue;
00151 else if (norm < 0.5) return Qt::blue;
00152 else if (norm < 0.625) return Qt::darkYellow;
00153 else if (norm < 0.75) return Qt::yellow;
00154 else if (norm < 0.875) return Qt::darkRed;
00155 else return Qt::red;
00156 break;
00157
00158 case Highlight:
00159 if (norm > 0.99) return Qt::white;
00160 else return Qt::darkBlue;
00161
00162 case Printer:
00163 if (norm > 0.8) {
00164 r = 1.f;
00165 } else if (norm > 0.7) {
00166 r = 0.9f;
00167 } else if (norm > 0.6) {
00168 r = 0.8f;
00169 } else if (norm > 0.5) {
00170 r = 0.7f;
00171 } else if (norm > 0.4) {
00172 r = 0.6f;
00173 } else if (norm > 0.3) {
00174 r = 0.5f;
00175 } else if (norm > 0.2) {
00176 r = 0.4f;
00177 } else {
00178 r = 0.f;
00179 }
00180 r = g = b = 1.f - r;
00181 hsv = false;
00182 break;
00183 }
00184
00185 if (hsv) {
00186 return QColor::fromHsvF(h, s, v);
00187 } else {
00188 return QColor::fromRgbF(r, g, b);
00189 }
00190 }
00191
00192 QColor
00193 ColourMapper::getContrastingColour() const
00194 {
00195 if (m_map >= getColourMapCount()) return Qt::white;
00196 StandardMap map = (StandardMap)m_map;
00197
00198 switch (map) {
00199
00200 case DefaultColours:
00201 return QColor(255, 150, 50);
00202
00203 case WhiteOnBlack:
00204 return Qt::red;
00205
00206 case BlackOnWhite:
00207 return Qt::darkGreen;
00208
00209 case RedOnBlue:
00210 return Qt::green;
00211
00212 case YellowOnBlack:
00213 return QColor::fromHsv(240, 255, 255);
00214
00215 case BlueOnBlack:
00216 return Qt::red;
00217
00218 case Sunset:
00219 return Qt::white;
00220
00221 case FruitSalad:
00222 return Qt::white;
00223
00224 case Banded:
00225 return Qt::cyan;
00226
00227 case Highlight:
00228 return Qt::red;
00229
00230 case Printer:
00231 return Qt::red;
00232 }
00233
00234 return Qt::white;
00235 }
00236
00237 bool
00238 ColourMapper::hasLightBackground() const
00239 {
00240 if (m_map >= getColourMapCount()) return false;
00241 StandardMap map = (StandardMap)m_map;
00242
00243 switch (map) {
00244
00245 case BlackOnWhite:
00246 case Printer:
00247 return true;
00248
00249 default:
00250 return false;
00251 }
00252 }
00253
00254