Developer Documentation
HaltonColors.cc
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40 \*===========================================================================*/
41 
42 
43 //=============================================================================
44 //
45 // CLASS HaltonColors (by Marcel Campen)
46 //
47 //=============================================================================
48 
49 
50 //== INCLUDES =================================================================
51 
52 
53 #include <ACG/Utils/HaltonColors.hh>
54 
55 
56 //== NAMESPACES ===============================================================
57 
58 namespace ACG {
59 
60 //== CLASS IMPLEMENTATION =========================================================
61 
62 
64 {
65  // skip first 250 sequence elements to lower discrepancy even further.
66  current[0] = skip;
67  current[1] = skip;
68  current[2] = skip;
69 
70  // initialize prime bases for H,S,L. Especially the first should be small such that already
71  // small numbers of generated colors are distributed over the whole color circle.
72  bases[0] = 5;
73  bases[1] = 13;
74  bases[2] = 17;
75 
76  inverse_bases[0] = 1.0f / bases[0];
77  inverse_bases[1] = 1.0f / bases[1];
78  inverse_bases[2] = 1.0f / bases[2];
79 }
80 
81 float HaltonColors::halton(int index)
82 {
83  int base = bases[index];
84  float inverse_base = inverse_bases[index];
85  float H = 0;
86  float half = inverse_base;
87  int I = current[index];
88  current[index] += 1;
89  while (I > 0) {
90  int digit = I % base;
91  H = H + half * digit;
92  I = (int)(inverse_base * (I - digit));
93  half *= inverse_base;
94  }
95  return H;
96 }
97 
98 float HaltonColors::random_interval(int index, float min, float max)
99 {
100  return halton(index) * (max - min) + min;
101 }
102 
103 ACG::Vec4f HaltonColors::HSL2RGB(double h, double sl, double l)
104 {
105  double v;
106  double r, g, b;
107 
108  r = l;
109  g = l;
110  b = l;
111 
112  v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
113 
114  if (v > 0) {
115  double m;
116  double sv;
117  int sextant;
118  double fract, vsf, mid1, mid2;
119 
120  m = l + l - v;
121  sv = (v - m) / v;
122  h *= 6.0;
123  sextant = (int) h;
124  fract = h - sextant;
125  vsf = v * sv * fract;
126  mid1 = m + vsf;
127  mid2 = v - vsf;
128 
129  switch (sextant) {
130  case 0:
131  r = v;
132  g = mid1;
133  b = m;
134  break;
135  case 1:
136  r = mid2;
137  g = v;
138  b = m;
139  break;
140  case 2:
141  r = m;
142  g = v;
143  b = mid1;
144  break;
145  case 3:
146  r = m;
147  g = mid2;
148  b = v;
149  break;
150  case 4:
151  r = mid1;
152  g = m;
153  b = v;
154  break;
155  case 5:
156  r = v;
157  g = m;
158  b = mid2;
159  break;
160  }
161  }
162 
163  return Vec4f((float)r, (float)g, (float)b, 1.0f);
164 }
165 
167  float h = random_interval(0, 0.0f , 0.9f ); // 0.9 instead of 1.0 to suppress natural bias towards red
168  float s = random_interval(1, 0.40f, 0.80f); // saturation between 40% and 80%
169  float l = random_interval(2, 0.30f, 0.60f); // lightness between 30% and 60%
170  return HSL2RGB(h, s, l);
171 }
172 
174 {
175  return generateNextColor();
176 }
177 
178 
179 //=============================================================================
180 } // ACG namespace end
181 //=============================================================================
182 //=============================================================================
183 
Namespace providing different geometric functions concerning angles.
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
HaltonColors(int skip=250)
Default constructor.
Definition: HaltonColors.cc:63
ACG::Vec4f get_next_color()
Generate the next color (legacy method)
virtual ACG::Vec4f generateNextColor()
Generate the next color.