Lagrange
Color.h
1/*
2 * Copyright 2019 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <Eigen/Core>
15
16#include <algorithm>
17#include <cmath>
18#include <random>
19
20namespace lagrange {
21namespace ui {
22
23class Color : public Eigen::Vector4f
24{
25public:
26 using BaseType = Eigen::Vector4f;
27
28 static Color empty() { return Color(0, 0, 0, 0); }
29 static Color zero() { return Color(0, 0, 0, 0); }
30 static Color black() { return Color(0, 0, 0); }
31 static Color white() { return Color(1, 1, 1); }
32
33 static Color red() { return Color(1, 0, 0); }
34 static Color green() { return Color(0, 1, 0); }
35 static Color blue() { return Color(0, 0, 1); }
36
37 static Color cyan() { return Color(0, 1, 1); }
38 static Color yellow() { return Color(1, 1, 0); }
39 static Color purple() { return Color(1, 0, 1); }
40
41 Color(const Eigen::Vector4f& color)
42 : Eigen::Vector4f(color)
43 {}
44
45 Color(const Eigen::Vector3f& rgb, float alpha = 1.0f)
46 : Eigen::Vector4f(rgb.x(), rgb.y(), rgb.z(), alpha)
47 {}
48
49 Color(const float r, const float g, const float b, const float a)
50 : Color(Eigen::Vector4f(r, g, b, a))
51 {}
52
53 Color(const float r, const float g, const float b)
54 : Color(r, g, b, 1.0f)
55 {}
56
57 Color(const float v)
58 : Color(v, v, v, 1.0f)
59 {}
60
61 Color()
62 : Color(0, 0, 0, 0)
63 {}
64
65 template <typename Derived>
66 Color(const Eigen::MatrixBase<Derived>& p)
67 : Eigen::Vector4f(p)
68 {}
69
70 template <typename Derived>
71 Color& operator=(const Eigen::MatrixBase<Derived>& p)
72 {
73 this->Eigen::Vector4f::operator=(p);
74 return *this;
75 }
76
77 float& r() { return x(); }
78 float r() const { return x(); }
79
80 float& g() { return y(); }
81 float g() const { return y(); }
82
83 float& b() { return z(); }
84 float b() const { return z(); }
85
86 float& a() { return coeffRef(3); }
87 float a() const { return coeff(3); }
88
89 Eigen::Vector3f to_vec3() const { return Eigen::Vector3f(x(), y(), z()); }
90 Eigen::Vector4f to_vec4() const { return Eigen::Vector4f(x(), y(), z(), a()); }
91
92 Color operator+(const float v) const { return Color(r() + v, g() + v, b() + v, a()); }
93 Color operator-(const float v) const { return Color(r() - v, g() - v, b() - v, a()); }
94 Color operator/(const float v) const { return Color(r() / v, g() / v, b() / v, a()); }
95 Color operator*(const float v) const { return Color(r() * v, g() * v, b() * v, a()); }
96
97 Color operator+(const Color c) const
98 {
99 return Color(r() + c.r(), g() + c.g(), b() + c.b(), std::max(a(), c.a()));
100 }
101 Color operator-(const Color c) const
102 {
103 return Color(r() - c.r(), g() - c.g(), b() - c.b(), std::max(a(), c.a()));
104 }
105
109 void clamp()
110 {
111 if (r() < 0.0f) r() = 0.0f;
112 if (r() > 1.0f) r() = 1.0f;
113 if (g() < 0.0f) g() = 0.0f;
114 if (g() > 1.0f) g() = 1.0f;
115 if (b() < 0.0f) b() = 0.0f;
116 if (b() > 1.0f) b() = 1.0f;
117 }
118
119 Color clamped() const
120 {
121 return Color(
122 std::max(std::min(r(), 1.0f), 0.0f),
123 std::max(std::min(g(), 1.0f), 0.0f),
124 std::max(std::min(b(), 1.0f), 0.0f),
125 std::max(std::min(a(), 1.0f), 0.0f));
126 }
127
128 inline bool is_white() { return (r() + g() + b()) >= 3; }
129
130 inline bool is_black() { return (r() == 0 && g() == 0 && b() == 0); }
131
132 float distance(const Color c) const
133 {
134 return std::abs(c.r() - r()) + std::abs(c.g() - g()) + std::abs(c.b() - b());
135 }
136
146 template <typename URBG>
147 static const Color random_from(URBG&& urbg)
148 {
149 // static float tau = 0.5f;
150 //tau += (1.25f + (float)rand() / RAND_MAX);
151 std::uniform_real_distribution<float> dist(0.f, 2.f * M_PI);
152 float tau = dist(urbg);
153
154 const float value = static_cast<float>(M_PI) / 3.0f;
155
156 float center = 0.3f; // magic numbers!
157 float width = 0.3f;
158 return Color(
159 std::sin(tau + 0.0f * value) * width + center,
160 std::sin(tau + 2.0f * value) * width + center,
161 std::sin(tau + 4.0f * value) * width + center);
162 }
163
164 // given a number, will always return the same color for the same number, and will produce
165 // reasonably different colors for different numbers.
166 static const Color random(int i)
167 {
168 float tau = (float)i;
169 float value = (float)M_PI / 3;
170 float center = 0.3f;
171 float width = 0.3f;
172 return Color(
173 std::sin(tau + 0.0f * value) * width + center,
174 std::sin(tau + 2.0f * value) * width + center,
175 std::sin(tau + 4.0f * value) * width + center);
176 }
177
178 static Color integer_to_color(int i)
179 {
180 int r = (i & 0x000000FF);
181 int g = (i & 0x0000FF00) >> 8;
182 int b = (i & 0x00FF0000) >> 16;
183 return Color(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
184 }
185 int to_integer() const
186 {
187 int r = int(x() * 255.0f);
188 int g = int(y() * 255.0f) << 8;
189 int b = int(z() * 255.0f) << 16;
190 return (r | g) | b;
191 }
192};
193} // namespace ui
194} // namespace lagrange
Definition: Color.h:24
void clamp()
Clamps the color.
Definition: Color.h:109
static const Color random_from(URBG &&urbg)
Get a random color.
Definition: Color.h:147
Lagrange UI Viewer and mini 3D engine.
Definition: AcceleratedPicking.h:22
Main namespace for Lagrange.
Definition: AABBIGL.h:30