SPH
Color.h
Go to the documentation of this file.
1 #pragma once
2 
4 #include <wx/colour.h>
5 
7 
8 class Rgba {
9 private:
10  BasicVector<float> data;
11 
12  Rgba(const BasicVector<float>& data)
13  : data(data) {}
14 
15 public:
16  Rgba() = default;
17 
18  Rgba(const float r, const float g, const float b, const float a = 1.f)
19  : data(r, g, b, a) {}
20 
21  explicit Rgba(const float gray, const float a = 1.f)
22  : data(gray, gray, gray, a) {}
23 
24  Rgba(const Rgba& other)
25  : data(other.data) {}
26 
27  explicit Rgba(const wxColour& other)
28  : data(other.Red() / 255.f, other.Green() / 255.f, other.Blue() / 255.f, 1.f) {}
29 
30  Rgba& operator=(const Rgba& other) {
31  data = other.data;
32  return *this;
33  }
34 
35  explicit operator wxColour() const {
36  return wxColour(getByte(data[0]), getByte(data[1]), getByte(data[2]));
37  }
38 
39  float& r() {
40  return data[0];
41  }
42 
43  float r() const {
44  return data[0];
45  }
46 
47  float& g() {
48  return data[1];
49  }
50 
51  float g() const {
52  return data[1];
53  }
54 
55  float& b() {
56  return data[2];
57  }
58 
59  float b() const {
60  return data[2];
61  }
62 
63  float& a() {
64  return data[3];
65  }
66 
67  float a() const {
68  return data[3];
69  }
70 
74  Rgba operator*(const float value) const {
75  return preserveAlpha(data * value);
76  }
77 
81  Rgba operator/(const float value) const {
82  return preserveAlpha(data / value);
83  }
84 
89  Rgba operator*(const Rgba& other) const {
90  return preserveAlpha(data * other.data);
91  }
92 
97  Rgba operator+(const Rgba& other) const {
98  return preserveAlpha(data + other.data);
99  }
100 
101  Rgba& operator+=(const Rgba& other) {
102  *this = *this + other;
103  return *this;
104  }
105 
106  bool operator==(const Rgba& other) const {
107  return data == other.data;
108  }
109 
110  bool operator!=(const Rgba& other) const {
111  return data != other.data;
112  }
113 
115  float intensity() const {
116  return 0.2126f * data[0] + 0.7152f * data[1] + 0.0722f * data[2];
117  }
118 
120  Rgba over(const Rgba& other) const {
121  const float a1 = other.a();
122  const float a2 = this->a();
123  const float ar = a2 + a1 * (1.f - a2);
124  if (ar == 0.f) {
125  // blending two fully transparent colors
126  return transparent();
127  }
128  SPH_ASSERT(ar > 0.f);
129  Rgba color = (data * a2 + other.data * a1 * (1.f - a2)) / ar;
130  color.a() = ar;
131  return color;
132  }
133 
137  Rgba darken(const float amount) const {
138  SPH_ASSERT(amount >= 0.f && amount <= 1.f);
139  return preserveAlpha(*this * (1.f - amount));
140  }
141 
145  Rgba brighten(const float amount) const {
146  SPH_ASSERT(amount >= 0.f);
147  return preserveAlpha(*this * (1.f + amount));
148  }
149 
151  Rgba inverse() const {
152  return preserveAlpha(max(BasicVector<float>(1.f) - data, BasicVector<float>(0.f)));
153  }
154 
158  Rgba blend(const Rgba& other, const float amount) const {
159  return Rgba(lerp(data, other.data, amount));
160  }
161 
166  Rgba saturate(const float value) const {
167  const float Pr = 0.299f;
168  const float Pg = 0.587f;
169  const float Pb = 0.114f;
170  const float P = sqrt(sqr(data[0]) * Pr + sqr(data[1]) * Pg + sqr(data[2]) * Pb);
171  Rgba result = *this;
172  result.r() = P + (data[0] - P) * value;
173  result.g() = P + (data[1] - P) * value;
174  result.b() = P + (data[2] - P) * value;
175  return result;
176  }
177 
178  static Rgba red() {
179  return Rgba(1.f, 0.f, 0.f);
180  }
181 
182  static Rgba green() {
183  return Rgba(0.f, 1.f, 0.f);
184  }
185 
186  static Rgba blue() {
187  return Rgba(0.f, 0.f, 1.f);
188  }
189 
190  static Rgba black() {
191  return Rgba(0.f, 0.f, 0.f);
192  }
193 
194  static Rgba white() {
195  return Rgba(1.f, 1.f, 1.f);
196  }
197 
198  static Rgba gray(const float value = 0.5f) {
199  return Rgba(value, value, value);
200  }
201 
202  static Rgba transparent() {
203  return Rgba(0.f, 0.f, 0.f, 0.f);
204  }
205 
206 private:
207  Rgba preserveAlpha(const Rgba& color) const {
208  Rgba result = color;
209  result.a() = data[3];
210  return result;
211  }
212 
213  int getByte(const float f) const {
214  return clamp(int(f * 255.f), 0, 255);
215  }
216 };
217 
218 class Hsv {
219 private:
220  BasicVector<float> data;
221 
222 public:
223  Hsv(const float h, const float s, const float v)
224  : data(h, s, v) {}
225 
226  float& operator[](const int index) {
227  SPH_ASSERT(index < 3);
228  return data[index];
229  }
230 
231  float& h() {
232  return data[0];
233  }
234 
235  float h() const {
236  return data[0];
237  }
238 
239  float& s() {
240  return data[1];
241  }
242 
243  float s() const {
244  return data[1];
245  }
246 
247  float& v() {
248  return data[2];
249  }
250 
251  float v() const {
252  return data[2];
253  }
254 };
255 /*
256 template <>
257 inline Hsv convert(const Rgba& rgb) {
258  const float cmin = min(rgb.r(), rgb.g(), rgb.b());
259  const float cmax = max(rgb.r(), rgb.g(), rgb.b());
260  const float delta = cmax - cmin;
261  if (delta < 1.e-3f) {
262  return Hsv(0.f, 0.f, cmax);
263  }
264  const float v = cmax;
265  const float s = (cmax < 1.e-3f) ? 0.f : delta / cmax;
266  float h;
267  if (cmax == rgb.r()) {
268  h = (rgb.g() - rgb.b()) / delta;
269  } else if (cmax == rgb.g()) {
270  h = 2.f + (rgb.b() - rgb.r()) / delta;
271  } else {
272  h = 4.f + (rgb.r() - rgb.g()) / delta;
273  }
274  if (h >= 0.f) {
275  h /= 6.f;
276  } else {
277  h = h / 6.f + 1.f;
278  }
279  return Hsv(h, s, v);
280 }
281 
282 template <>
283 inline Rgba convert(const Hsv& hsv) {
284  if (hsv.s() == 0.f) {
285  return Rgba(hsv.v());
286  }
287  const float h = hsv.h() * 6.f;
288  const int hidx = int(h);
289  const float diff = h - hidx;
290  const float p = hsv.v() * (1.f - hsv.s());
291  const float q = hsv.v() * (1.f - (hsv.s() * diff));
292  const float t = hsv.v() * (1.f - (hsv.s() * (1.f - diff)));
293 
294  switch (hidx) {
295  case 0:
296  return Rgba(hsv.v(), t, p);
297  case 1:
298  return Rgba(q, hsv.v(), p);
299  case 2:
300  return Rgba(p, hsv.v(), t);
301  case 3:
302  return Rgba(p, q, hsv.v());
303  case 4:
304  return Rgba(t, p, hsv.v());
305  default:
306  return Rgba(hsv.v(), p, q);
307  }
308 }
309 */
310 
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
constexpr INLINE T max(const T &f1, const T &f2)
Definition: MathBasic.h:20
constexpr INLINE T clamp(const T &f, const T &f1, const T &f2)
Definition: MathBasic.h:35
INLINE T lerp(const T v1, const T v2, const TAmount amount)
Definition: MathUtils.h:341
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
INLINE T sqrt(const T f)
Return a squared root of a value.
Definition: MathUtils.h:78
#define NAMESPACE_SPH_END
Definition: Object.h:12
Basic vector algebra. Computations are accelerated using SIMD.
3-dimensional vector, float precision
Definition: Vector.h:57
Definition: Color.h:218
float & h()
Definition: Color.h:231
float & v()
Definition: Color.h:247
float & s()
Definition: Color.h:239
Hsv(const float h, const float s, const float v)
Definition: Color.h:223
float h() const
Definition: Color.h:235
float s() const
Definition: Color.h:243
float & operator[](const int index)
Definition: Color.h:226
float v() const
Definition: Color.h:251
Definition: Color.h:8
Rgba brighten(const float amount) const
Returns a color brighter by given factor.
Definition: Color.h:145
static Rgba gray(const float value=0.5f)
Definition: Color.h:198
Rgba inverse() const
Returns an inverse color.
Definition: Color.h:151
Rgba saturate(const float value) const
Retuns a color with modified saturation.
Definition: Color.h:166
Rgba()=default
static Rgba green()
Definition: Color.h:182
float intensity() const
Returns the average intensity of the color.
Definition: Color.h:115
Rgba(const float gray, const float a=1.f)
Definition: Color.h:21
Rgba darken(const float amount) const
Returns a color darker by given factor.
Definition: Color.h:137
static Rgba black()
Definition: Color.h:190
float b() const
Definition: Color.h:59
float & a()
Definition: Color.h:63
static Rgba transparent()
Definition: Color.h:202
Rgba operator*(const float value) const
Multiplies the intensity of the color by given factor.
Definition: Color.h:74
static Rgba white()
Definition: Color.h:194
float a() const
Definition: Color.h:67
static Rgba blue()
Definition: Color.h:186
Rgba(const wxColour &other)
Definition: Color.h:27
Rgba operator/(const float value) const
Divides the intensity of the color by given factor.
Definition: Color.h:81
Rgba(const float r, const float g, const float b, const float a=1.f)
Definition: Color.h:18
bool operator!=(const Rgba &other) const
Definition: Color.h:110
float & g()
Definition: Color.h:47
float & r()
Definition: Color.h:39
Rgba & operator=(const Rgba &other)
Definition: Color.h:30
float & b()
Definition: Color.h:55
bool operator==(const Rgba &other) const
Definition: Color.h:106
static Rgba red()
Definition: Color.h:178
float r() const
Definition: Color.h:43
Rgba over(const Rgba &other) const
Blends two colors together using "over" operation.
Definition: Color.h:120
Rgba & operator+=(const Rgba &other)
Definition: Color.h:101
Rgba operator*(const Rgba &other) const
Multiplies the color by other color, component-wise.
Definition: Color.h:89
Rgba(const Rgba &other)
Definition: Color.h:24
Rgba operator+(const Rgba &other) const
Returns the sum of two colors, component-wise.
Definition: Color.h:97
Rgba blend(const Rgba &other, const float amount) const
Computes a linear interpolation of two color.
Definition: Color.h:158
float g() const
Definition: Color.h:51