d9eb98efe8dc5297c199444422f6724a35056bcd
[gencolormap.git] / colormap.hpp
1 /*
2  * Copyright (C) 2015 Computer Graphics Group, University of Siegen
3  * Written by Martin Lambers <martin.lambers@uni-siegen.de>
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23
24 #ifndef COLORMAP_HPP
25 #define COLORMAP_HPP
26
27 /* Generate color maps for scientific visualization purposes.
28  *
29  * Usage:
30  * - Decide which type of color map you need and how many colors the map should
31  *   contain.
32  * - Allocate memory for you color map (3 * unsigned char for each color entry).
33  * - Call the function that generates your color map.
34  *
35  * All colors are represented as unsigned char sRGB triplets, with each value in
36  * [0,255].
37  */
38
39 namespace ColorMap {
40
41 /*
42  * Brewer-like color maps, as described in
43  * M. Wijffelaars, R. Vliegen, J.J. van Wijk, E.-J. van der Linden. Generating
44  * color palettes using intuitive parameters. In Computer Graphics Forum, vol. 27,
45  * no. 3, pp. 743-750, 2008.
46  */
47
48 // Create a sequential color map with n colors of the given hue in [0,2*PI].
49
50 const float BrewerSequentialDefaultHue = 0.0;
51 const float BrewerSequentialDefaultContrast = 0.88f;
52 float BrewerSequentialDefaultContrastForSmallN(int n); // only for discrete color maps, i.e. n <= 9
53 const float BrewerSequentialDefaultSaturation = 0.6f;
54 const float BrewerSequentialDefaultBrightness = 0.75f;
55 const float BrewerSequentialDefaultWarmth = 0.15f;
56
57 void BrewerSequential(int n, unsigned char* srgb_colormap,
58         float hue = BrewerSequentialDefaultHue,
59         float contrast = BrewerSequentialDefaultContrast,
60         float saturation = BrewerSequentialDefaultSaturation,
61         float brightness = BrewerSequentialDefaultBrightness,
62         float warmth = BrewerSequentialDefaultWarmth);
63
64 // Create a diverging color map with n colors. Half of them will have the given
65 // hue (in [0,2*PI]), the other half will have a hue that has the distance given
66 // by divergence (in [0,2*PI]) to that hue, and they will meet in the middle at
67 // a neutral color.
68
69 const float BrewerDivergingDefaultHue = 0.0;
70 const float BrewerDivergingDefaultDivergence = 4.18879020479f; // 2/3 * 2PI
71 const float BrewerDivergingDefaultContrast = 0.88f;
72 float BrewerDivergingDefaultContrastForSmallN(int n); // only for discrete color maps, i.e. n <= 9
73 const float BrewerDivergingDefaultSaturation = 0.6f;
74 const float BrewerDivergingDefaultBrightness = 0.75f;
75 const float BrewerDivergingDefaultWarmth = 0.15f;
76
77 void BrewerDiverging(int n, unsigned char* srgb_colormap,
78         float hue = BrewerDivergingDefaultHue,
79         float divergence = BrewerDivergingDefaultDivergence,
80         float contrast = BrewerDivergingDefaultContrast,
81         float saturation = BrewerDivergingDefaultSaturation,
82         float brightness = BrewerDivergingDefaultBrightness,
83         float warmth = BrewerDivergingDefaultWarmth);
84
85 // Create a qualitative color map with n colors. The colors will have the same
86 // saturation; lightness and hue will differ. The parameter hue sets the hue of
87 // the first color, and the parameter divergence defines the hue range starting
88 // from that hue that can be used for the colors.
89
90 const float BrewerQualitativeDefaultHue = 0.0f;
91 const float BrewerQualitativeDefaultDivergence = 4.18879020479f; // 2/3 * 2PI
92 const float BrewerQualitativeDefaultContrast = 0.5f;
93 const float BrewerQualitativeDefaultSaturation = 0.5f;
94 const float BrewerQualitativeDefaultBrightness = 0.8f;
95
96 void BrewerQualitative(int n, unsigned char* colormap,
97         float hue = BrewerQualitativeDefaultHue,
98         float divergence = BrewerQualitativeDefaultDivergence,
99         float contrast = BrewerQualitativeDefaultContrast,
100         float saturation = BrewerQualitativeDefaultSaturation,
101         float brightness = BrewerQualitativeDefaultBrightness);
102
103 /*
104  * Perceptually linear (PL) color maps.
105  *
106  * These are computed in CIELUV/LCH to achieve perceptual linearity.
107  * One or two of lightness, saturation, and hue are changed while the other(s)
108  * stay constant.
109  *
110  * For example, color maps of constant lightness are useful for 3D surfaces
111  * because they do not interfere with additional shading.
112  */
113
114 /* Sequential perceptually linear maps */
115
116 // Varying lightness
117
118 const float PLSequentialLightnessDefaultSaturation = 0.5f;
119 const float PLSequentialLightnessDefaultHue = 0.349065850399f; // 20 deg
120
121 void PLSequentialLightness(int n, unsigned char* colormap,
122         float saturation = PLSequentialLightnessDefaultSaturation,
123         float hue = PLSequentialLightnessDefaultHue);
124
125 // Varying saturation
126
127 const float PLSequentialSaturationDefaultLightness = 0.5f;
128 const float PLSequentialSaturationDefaultSaturation = 0.5f;
129 const float PLSequentialSaturationDefaultHue = 0.349065850399f; // 20 deg
130
131 void PLSequentialSaturation(int n, unsigned char* colormap,
132         float lightness = PLSequentialSaturationDefaultLightness,
133         float saturation = PLSequentialSaturationDefaultSaturation,
134         float hue = PLSequentialSaturationDefaultHue);
135
136 // Varying hue (through all colors, rainbow-like)
137
138 const float PLSequentialRainbowDefaultHue = 0.0f;
139 const float PLSequentialRainbowDefaultRotations = -1.5f;
140 const float PLSequentialRainbowDefaultSaturation = 1.2f;
141
142 void PLSequentialRainbow(int n, unsigned char* colormap,
143         float hue = PLSequentialRainbowDefaultHue,
144         float rotations = PLSequentialRainbowDefaultRotations,
145         float saturation = PLSequentialRainbowDefaultSaturation);
146
147 // Varying hue (through physically plausible black body colors at increasing
148 // temperatures).
149 // The defaults are chosen so that we start at red and arrive at the D65 white
150 // point (6500 K), thus excluding the blue colors that occur at higher
151 // temperatures.
152 const float PLSequentialBlackBodyDefaultTemperature = 250.0f;
153 const float PLSequentialBlackBodyDefaultRange = 6250.0f;
154 const float PLSequentialBlackBodyDefaultSaturation = 2.5f;
155
156 void PLSequentialBlackBody(int n, unsigned char* colormap,
157         float temperature = PLSequentialBlackBodyDefaultTemperature,
158         float range = PLSequentialBlackBodyDefaultRange,
159         float saturation = PLSequentialBlackBodyDefaultSaturation);
160
161 /* Diverging perceptually linear maps */
162
163 // Varying lightness
164
165 const float PLDivergingLightnessDefaultLightness = 0.1f;
166 const float PLDivergingLightnessDefaultSaturation = 0.5f;
167 const float PLDivergingLightnessDefaultHue = 0.349065850399f; // 20 deg
168 const float PLDivergingLightnessDefaultDivergence = 4.18879020479f; // 2/3 * 2PI
169
170 void PLDivergingLightness(int n, unsigned char* colormap,
171         float lightness = PLDivergingLightnessDefaultLightness,
172         float saturation = PLDivergingLightnessDefaultSaturation,
173         float hue = PLDivergingLightnessDefaultHue,
174         float divergence = PLDivergingLightnessDefaultDivergence);
175
176 // Varying saturation
177
178 const float PLDivergingSaturationDefaultLightness = 0.5f;
179 const float PLDivergingSaturationDefaultSaturation = 0.5f;
180 const float PLDivergingSaturationDefaultHue = 0.349065850399f; // 20 deg
181 const float PLDivergingSaturationDefaultDivergence = 4.18879020479f; // 2/3 * 2PI
182
183 void PLDivergingSaturation(int n, unsigned char* colormap,
184         float lightness = PLDivergingSaturationDefaultLightness,
185         float saturation = PLDivergingSaturationDefaultSaturation,
186         float hue = PLDivergingSaturationDefaultHue,
187         float divergence = PLDivergingSaturationDefaultDivergence);
188
189 /* Qualitative perceptually linear maps */
190
191 const float PLQualitativeHueDefaultLightness = 0.55f;
192 const float PLQualitativeHueDefaultSaturation = 0.35f;
193 const float PLQualitativeHueDefaultHue = 0.0f;
194
195 void PLQualitativeHue(int n, unsigned char* colormap,
196         float lightness = PLQualitativeHueDefaultLightness,
197         float saturation = PLQualitativeHueDefaultSaturation,
198         float hue = PLQualitativeHueDefaultHue);
199
200 /*
201  * CubeHelix color maps, as described in
202  * Green, D. A., 2011, A colour scheme for the display of astronomical intensity
203  * images, Bulletin of the Astronomical Society of India, 39, 289.
204  */
205
206 // Create a CubeHelix colormap with n colors. The parameter hue (in [0,2*PI])
207 // sets the hue of the first color. The parameter rot sets the number of
208 // rotations. It can be negative for backwards rotation. The saturation parameter
209 // determines the saturation of the colors; higher values may lead to clipping
210 // of colors in the sRGB space. The gamma parameter sets optional gamma correction.
211 // The return value is the number of colors that had to be clipped.
212
213 const float CubeHelixDefaultHue = 0.523598775598f; // 1/12 * 2PI
214 const float CubeHelixDefaultRotations = -1.5f;
215 const float CubeHelixDefaultSaturation = 1.2f;
216 const float CubeHelixDefaultGamma = 1.0f;
217
218 int CubeHelix(int n, unsigned char* colormap,
219         float hue = CubeHelixDefaultHue,
220         float rotations = CubeHelixDefaultRotations,
221         float saturation = CubeHelixDefaultSaturation,
222         float gamma = CubeHelixDefaultGamma);
223
224 /*
225  * Moreland color maps, as described in
226  * K. Moreland, Diverging Color Maps for Scientific Visualization, Proc. Int.
227  * Symp. Visual Computing, December 2009, DOI 10.1007/978-3-642-10520-3_9.
228  */
229
230 // Create a Moreland colormap with n colors. Specify the two endpoints
231 // of the colormap as sRGB colors; all intermediate colors will be generated.
232
233 const unsigned char MorelandDefaultR0 = 180;
234 const unsigned char MorelandDefaultG0 = 4;
235 const unsigned char MorelandDefaultB0 = 38;
236 const unsigned char MorelandDefaultR1 = 59;
237 const unsigned char MorelandDefaultG1 = 76;
238 const unsigned char MorelandDefaultB1 = 192;
239
240 void Moreland(int n, unsigned char* colormap,
241         unsigned char sr0 = MorelandDefaultR0,
242         unsigned char sg0 = MorelandDefaultG0,
243         unsigned char sb0 = MorelandDefaultB0,
244         unsigned char sr1 = MorelandDefaultR1,
245         unsigned char sg1 = MorelandDefaultG1,
246         unsigned char sb1 = MorelandDefaultB1);
247
248 /*
249  * McNames color maps, as described in
250  * J. McNames, An Effective Color Scale for Simultaneous Color and Gray-Scale Publications,
251  * IEEE Signal Processing Magazine 23(1), January 2006, DOI 10.1109/MSP.2006.1593340.
252  *
253  * Note: Use CubeHelix instead! The McNames color maps are perceptually not linear in luminance!
254  */
255
256 // Create a McNames colormap with n colors. Specify the number of
257 // periods.
258
259 const float McNamesDefaultPeriods = 2.0f;
260
261 void McNames(int n, unsigned char* colormap,
262         float periods = McNamesDefaultPeriods);
263
264 }
265
266 #endif