annotate layer/ColourMapper.cpp @ 197:6b023411087b

* Work on harmonising colour and scale ranges between types of layer * Add normalize options to colour 3d plot layer
author Chris Cannam
date Thu, 01 Feb 2007 14:31:28 +0000
parents 22c99c8aa1e0
children 1ab31723825d
rev   line source
Chris@196 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@196 2
Chris@196 3 /*
Chris@196 4 Sonic Visualiser
Chris@196 5 An audio file viewer and annotation editor.
Chris@196 6 Centre for Digital Music, Queen Mary, University of London.
Chris@196 7 This file copyright 2006-2007 Chris Cannam and QMUL.
Chris@196 8
Chris@196 9 This program is free software; you can redistribute it and/or
Chris@196 10 modify it under the terms of the GNU General Public License as
Chris@196 11 published by the Free Software Foundation; either version 2 of the
Chris@196 12 License, or (at your option) any later version. See the file
Chris@196 13 COPYING included with this distribution for more information.
Chris@196 14 */
Chris@196 15
Chris@196 16 #include "ColourMapper.h"
Chris@196 17
Chris@197 18 #include <iostream>
Chris@197 19
Chris@196 20 ColourMapper::ColourMapper(int map, float min, float max) :
Chris@196 21 QObject(),
Chris@196 22 m_map(map),
Chris@196 23 m_min(min),
Chris@196 24 m_max(max)
Chris@196 25 {
Chris@197 26 if (m_min == m_max) {
Chris@197 27 std::cerr << "WARNING: ColourMapper: min == max (== " << m_min
Chris@197 28 << "), adjusting" << std::endl;
Chris@197 29 m_max = m_min + 1;
Chris@197 30 }
Chris@196 31 }
Chris@196 32
Chris@196 33 ColourMapper::~ColourMapper()
Chris@196 34 {
Chris@196 35 }
Chris@196 36
Chris@196 37 int
Chris@196 38 ColourMapper::getColourMapCount()
Chris@196 39 {
Chris@197 40 return 10;
Chris@196 41 }
Chris@196 42
Chris@196 43 QString
Chris@196 44 ColourMapper::getColourMapName(int n)
Chris@196 45 {
Chris@197 46 if (n >= getColourMapCount()) return tr("<unknown>");
Chris@196 47 StandardMap map = (StandardMap)n;
Chris@196 48
Chris@196 49 switch (map) {
Chris@196 50 case DefaultColours: return tr("Default");
Chris@196 51 case WhiteOnBlack: return tr("White on Black");
Chris@196 52 case BlackOnWhite: return tr("Black on White");
Chris@196 53 case RedOnBlue: return tr("Red on Blue");
Chris@196 54 case YellowOnBlack: return tr("Yellow on Black");
Chris@196 55 case BlueOnBlack: return tr("Blue on Black");
Chris@196 56 case Sunset: return tr("Sunset");
Chris@196 57 case FruitSalad: return tr("Fruit Salad");
Chris@197 58 case Banded: return tr("Banded");
Chris@197 59 case Highlight: return tr("Highlight");
Chris@196 60 }
Chris@196 61
Chris@196 62 return tr("<unknown>");
Chris@196 63 }
Chris@196 64
Chris@196 65 QColor
Chris@196 66 ColourMapper::map(float value) const
Chris@196 67 {
Chris@196 68 float norm = (value - m_min) / (m_max - m_min);
Chris@196 69 if (norm < 0.f) norm = 0.f;
Chris@196 70 if (norm > 1.f) norm = 1.f;
Chris@196 71
Chris@196 72 float h = 0.f, s = 0.f, v = 0.f, r = 0.f, g = 0.f, b = 0.f;
Chris@196 73 bool hsv = true;
Chris@196 74
Chris@196 75 float red = 0.f, green = 0.3333f, blue = 0.6666f, pieslice = 0.3333f;
Chris@196 76
Chris@197 77 if (m_map >= getColourMapCount()) return Qt::black;
Chris@196 78 StandardMap map = (StandardMap)m_map;
Chris@196 79
Chris@196 80 switch (map) {
Chris@196 81
Chris@196 82 case DefaultColours:
Chris@196 83 h = blue - norm * 2.f * pieslice;
Chris@196 84 s = 0.5f + norm/2.f;
Chris@196 85 v = norm;
Chris@196 86 break;
Chris@196 87
Chris@196 88 case WhiteOnBlack:
Chris@196 89 r = g = b = norm;
Chris@196 90 hsv = false;
Chris@196 91 break;
Chris@196 92
Chris@196 93 case BlackOnWhite:
Chris@196 94 r = g = b = 1.f - norm;
Chris@196 95 hsv = false;
Chris@196 96 break;
Chris@196 97
Chris@196 98 case RedOnBlue:
Chris@196 99 h = blue - pieslice/4.f + norm * (pieslice + pieslice/4.f);
Chris@196 100 s = 1.f;
Chris@196 101 v = norm;
Chris@196 102 break;
Chris@196 103
Chris@196 104 case YellowOnBlack:
Chris@196 105 h = 0.15f;
Chris@196 106 s = 1.f;
Chris@196 107 v = norm;
Chris@196 108 break;
Chris@196 109
Chris@196 110 case BlueOnBlack:
Chris@197 111 h = blue;
Chris@196 112 s = 1.f;
Chris@196 113 v = norm * 2.f;
Chris@197 114 if (v > 1.f) {
Chris@196 115 v = 1.f;
Chris@197 116 s = 1.f - (sqrtf(norm) - 0.707f) * 3.413f;
Chris@197 117 if (s < 0.f) s = 0.f;
Chris@197 118 if (s > 1.f) s = 1.f;
Chris@196 119 }
Chris@196 120 break;
Chris@196 121
Chris@196 122 case Sunset:
Chris@196 123 r = (norm - 0.24f) * 2.38f;
Chris@196 124 if (r > 1.f) r = 1.f;
Chris@196 125 if (r < 0.f) r = 0.f;
Chris@196 126 g = (norm - 0.64f) * 2.777f;
Chris@196 127 if (g > 1.f) g = 1.f;
Chris@196 128 if (g < 0.f) g = 0.f;
Chris@196 129 b = (3.6f * norm);
Chris@196 130 if (norm > 0.277f) b = 2.f - b;
Chris@196 131 if (b > 1.f) b = 1.f;
Chris@196 132 if (b < 0.f) b = 0.f;
Chris@196 133 hsv = false;
Chris@196 134 break;
Chris@196 135
Chris@196 136 case FruitSalad:
Chris@197 137 h = blue + (pieslice/6.f) - norm;
Chris@196 138 if (h < 0.f) h += 1.f;
Chris@196 139 s = 1.f;
Chris@196 140 v = 1.f;
Chris@196 141 break;
Chris@197 142
Chris@197 143 case Banded:
Chris@197 144 if (norm < 0.125) return Qt::darkGreen;
Chris@197 145 else if (norm < 0.25) return Qt::green;
Chris@197 146 else if (norm < 0.375) return Qt::darkBlue;
Chris@197 147 else if (norm < 0.5) return Qt::blue;
Chris@197 148 else if (norm < 0.625) return Qt::darkYellow;
Chris@197 149 else if (norm < 0.75) return Qt::yellow;
Chris@197 150 else if (norm < 0.875) return Qt::darkRed;
Chris@197 151 else return Qt::red;
Chris@197 152 break;
Chris@197 153
Chris@197 154 case Highlight:
Chris@197 155 if (norm > 0.99) return Qt::white;
Chris@197 156 else return Qt::darkBlue;
Chris@196 157 }
Chris@196 158
Chris@196 159 if (hsv) {
Chris@196 160 return QColor::fromHsvF(h, s, v);
Chris@196 161 } else {
Chris@196 162 return QColor::fromRgbF(r, g, b);
Chris@196 163 }
Chris@196 164 }
Chris@196 165
Chris@196 166 QColor
Chris@196 167 ColourMapper::getContrastingColour() const
Chris@196 168 {
Chris@197 169 if (m_map >= getColourMapCount()) return Qt::white;
Chris@196 170 StandardMap map = (StandardMap)m_map;
Chris@196 171
Chris@196 172 switch (map) {
Chris@196 173
Chris@196 174 case DefaultColours:
Chris@196 175 return QColor(255, 150, 50);
Chris@196 176
Chris@196 177 case WhiteOnBlack:
Chris@196 178 return Qt::red;
Chris@196 179
Chris@196 180 case BlackOnWhite:
Chris@196 181 return Qt::darkGreen;
Chris@196 182
Chris@196 183 case RedOnBlue:
Chris@196 184 return Qt::green;
Chris@196 185
Chris@196 186 case YellowOnBlack:
Chris@196 187 return QColor::fromHsv(240, 255, 255);
Chris@196 188
Chris@196 189 case BlueOnBlack:
Chris@196 190 return Qt::red;
Chris@196 191
Chris@196 192 case Sunset:
Chris@196 193 return Qt::white;
Chris@196 194
Chris@196 195 case FruitSalad:
Chris@196 196 return Qt::white;
Chris@197 197
Chris@197 198 case Banded:
Chris@197 199 return Qt::cyan;
Chris@197 200
Chris@197 201 case Highlight:
Chris@197 202 return Qt::red;
Chris@196 203 }
Chris@196 204
Chris@196 205 return Qt::white;
Chris@196 206 }
Chris@196 207
Chris@196 208