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  * $Revision$ *
45  * $Author$ *
46  * $Date$ *
47  * *
48 \*===========================================================================*/
49 
50 //=============================================================================
51 //
52 // CLASS HaltonColors (by Marcel Campen)
53 //
54 //=============================================================================
55 
56 
57 //== INCLUDES =================================================================
58 
59 
60 #include <ACG/Utils/HaltonColors.hh>
61 
62 
63 //== NAMESPACES ===============================================================
64 
65 namespace ACG {
66 
67 //== CLASS IMPLEMENTATION =========================================================
68 
69 
71 {
72  // skip first 250 sequence elements to lower discrepancy even further.
73  current[0] = skip;
74  current[1] = skip;
75  current[2] = skip;
76 
77  // initialize prime bases for H,S,L. Especially the first should be small such that already
78  // small numbers of generated colors are distributed over the whole color circle.
79  bases[0] = 5;
80  bases[1] = 13;
81  bases[2] = 17;
82 
83  inverse_bases[0] = 1.0f / bases[0];
84  inverse_bases[1] = 1.0f / bases[1];
85  inverse_bases[2] = 1.0f / bases[2];
86 }
87 
88 float HaltonColors::halton(int index)
89 {
90  int base = bases[index];
91  float inverse_base = inverse_bases[index];
92  float H = 0;
93  float half = inverse_base;
94  int I = current[index];
95  current[index] += 1;
96  while (I > 0) {
97  int digit = I % base;
98  H = H + half * digit;
99  I = (int)(inverse_base * (I - digit));
100  half *= inverse_base;
101  }
102  return H;
103 }
104 
105 float HaltonColors::random_interval(int index, float min, float max)
106 {
107  return halton(index) * (max - min) + min;
108 }
109 
110 ACG::Vec4f HaltonColors::HSL2RGB(double h, double sl, double l)
111 {
112  double v;
113  double r, g, b;
114 
115  r = l;
116  g = l;
117  b = l;
118 
119  v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
120 
121  if (v > 0) {
122  double m;
123  double sv;
124  int sextant;
125  double fract, vsf, mid1, mid2;
126 
127  m = l + l - v;
128  sv = (v - m) / v;
129  h *= 6.0;
130  sextant = (int) h;
131  fract = h - sextant;
132  vsf = v * sv * fract;
133  mid1 = m + vsf;
134  mid2 = v - vsf;
135 
136  switch (sextant) {
137  case 0:
138  r = v;
139  g = mid1;
140  b = m;
141  break;
142  case 1:
143  r = mid2;
144  g = v;
145  b = m;
146  break;
147  case 2:
148  r = m;
149  g = v;
150  b = mid1;
151  break;
152  case 3:
153  r = m;
154  g = mid2;
155  b = v;
156  break;
157  case 4:
158  r = mid1;
159  g = m;
160  b = v;
161  break;
162  case 5:
163  r = v;
164  g = m;
165  b = mid2;
166  break;
167  }
168  }
169 
170  return Vec4f((float)r, (float)g, (float)b, 1.0f);
171 }
172 
174  float h = random_interval(0, 0.0f , 0.9f ); // 0.9 instead of 1.0 to suppress natural bias towards red
175  float s = random_interval(1, 0.40f, 0.80f); // saturation between 40% and 80%
176  float l = random_interval(2, 0.30f, 0.60f); // lightness between 30% and 60%
177  return HSL2RGB(h, s, l);
178 }
179 
181 {
182  return generateNextColor();
183 }
184 
185 
186 //=============================================================================
187 } // ACG namespace end
188 //=============================================================================
189 //=============================================================================
190 
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:144
virtual ACG::Vec4f generateNextColor()
Generate the next color.
ACG::Vec4f get_next_color()
Generate the next color (legacy method)
HaltonColors(int skip=250)
Default constructor.
Definition: HaltonColors.cc:70
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51