color.cpp
Go to the documentation of this file.
1 #include "color.hpp"
2 
3 using namespace astra_ros;
4 
5 namespace
6 {
7  // HSV / RGB conversion code
8  // Adapted from:
9  // https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both
10  static Hsv rgb2hsv(const Rgb &in);
11  static Rgb hsv2rgb(const Hsv &in);
12 
13  Hsv rgb2hsv(const Rgb &in)
14  {
15  Hsv out;
16 
17  float min = in.r < in.g ? in.r : in.g;
18  min = min < in.b ? min : in.b;
19 
20  float max = in.r > in.g ? in.r : in.g;
21  max = max > in.b ? max : in.b;
22 
23  out.v = max; // v
24  const float delta = max - min;
25  if (delta < 0.0001f)
26  {
27  out.s = 0;
28  out.h = 0; // undefined, maybe nan?
29  return out;
30  }
31 
32  if (max > 0.0)
33  {
34  // NOTE: if Max is == 0, this divide would cause a crash
35  out.s = delta / max; // s
36  }
37  else
38  {
39  // if max is 0, then r = g = b = 0
40  // s = 0, h is undefined
41  out.s = 0.0;
42  out.h = NAN; // its now undefined
43  return out;
44  }
45 
46  if (in.r >= max)
47  {
48  out.h = (in.g - in.b) / delta; // between yellow & magenta
49  }
50  else if (in.g >= max)
51  {
52  out.h = 2.0f + (in.b - in.r) / delta; // between cyan & yellow
53  }
54  else
55  {
56  out.h = 4.0f + (in.r - in.g) / delta; // between magenta & cyan
57  }
58 
59  out.h *= 60.0f; // degrees
60 
61  if (out.h < 0.0f)
62  {
63  out.h += 360.0f;
64  }
65 
66  return out;
67  }
68 
69 
70  Rgb hsv2rgb(const Hsv &in)
71  {
72  Rgb out;
73 
74  if (in.s <= 0.0f)
75  {
76  out.r = in.v;
77  out.g = in.v;
78  out.b = in.v;
79  return out;
80  }
81 
82  float hh = in.h;
83  if(hh >= 360.0f) hh = 0.0f;
84  hh /= 60.0f;
85 
86  const long i = (long)hh;
87  const float ff = hh - i;
88  const float p = in.v * (1.0f - in.s);
89  const float q = in.v * (1.0f - (in.s * ff));
90  const float t = in.v * (1.0f - (in.s * (1.0f - ff)));
91 
92  switch(i)
93  {
94  case 0:
95  {
96  out.r = in.v;
97  out.g = t;
98  out.b = p;
99  break;
100  }
101  case 1:
102  {
103  out.r = q;
104  out.g = in.v;
105  out.b = p;
106  break;
107  }
108  case 2:
109  {
110  out.r = p;
111  out.g = in.v;
112  out.b = t;
113  break;
114  }
115  case 3:
116  {
117  out.r = p;
118  out.g = q;
119  out.b = in.v;
120  break;
121  }
122  case 4:
123  {
124  out.r = t;
125  out.g = p;
126  out.b = in.v;
127  break;
128  }
129  case 5:
130  default:
131  {
132  out.r = in.v;
133  out.g = p;
134  out.b = q;
135  break;
136  }
137  }
138 
139  return out;
140  }
141 
142  const static float GOLDEN_ANGLE = 137.507764f;
143 
144  float goldenHue(const std::size_t i)
145  {
146  return fmod(GOLDEN_ANGLE * i, 360.0f);
147  }
148 }
149 
151  : r(0.0f)
152  , g(0.0f)
153  , b(0.0f)
154  , a(1.0f)
155 {
156 }
157 
158 Rgba::Rgba(const float r, const float g, const float b, const float a)
159  : r(r)
160  , g(g)
161  , b(b)
162  , a(a)
163 {
164 }
165 
166 Rgba::operator std_msgs::ColorRGBA () const noexcept
167 {
168  std_msgs::ColorRGBA ret;
169  ret.r = r;
170  ret.g = g;
171  ret.b = b;
172  ret.a = a;
173  return ret;
174 }
175 
176 const Rgba Rgba::RED(1.0f, 0.0f, 0.0f, 1.0f);
177 const Rgba Rgba::GREEN(0.0f, 1.0f, 0.0f, 1.0f);
178 const Rgba Rgba::BLUE(0.0f, 0.0f, 1.0f, 1.0f);
179 const Rgba Rgba::WHITE(1.0f, 1.0f, 1.0f, 1.0f);
180 const Rgba Rgba::BLACK(0.0f, 0.0f, 0.0f, 1.0f);
181 
182 Rgba Rgba::fromRgb(const Rgb &rgb)
183 {
184  return fromRgb(rgb, 1.0);
185 }
186 
187 Rgba Rgba::fromRgb(const Rgb &rgb, const float a)
188 {
189  Rgba ret;
190  ret.a = a;
191  ret.r = rgb.r;
192  ret.g = rgb.g;
193  ret.b = rgb.b;
194  return ret;
195 }
196 
197 Rgba Rgba::fromHsv(const Hsv &hsv)
198 {
199  return fromRgb(Rgb::fromHsv(hsv));
200 }
201 
203  : r(0.0f)
204  , g(0.0f)
205  , b(0.0f)
206 {
207 }
208 
209 Rgb::Rgb(const float r, const float g, const float b)
210  : r(r)
211  , g(g)
212  , b(b)
213 {
214 }
215 
216 Rgb::operator std_msgs::ColorRGBA () const noexcept
217 {
218  std_msgs::ColorRGBA ret;
219  ret.r = r;
220  ret.g = g;
221  ret.b = b;
222  ret.a = 1.0f;
223  return ret;
224 }
225 
226 Rgb::operator Rgba () const noexcept
227 {
228  return toRgba();
229 }
230 
231 const Rgb Rgb::RED(1.0f, 0.0f, 0.0f);
232 const Rgb Rgb::GREEN(0.0f, 1.0f, 0.0f);
233 const Rgb Rgb::BLUE(0.0f, 0.0f, 1.0f);
234 const Rgb Rgb::WHITE(1.0f, 1.0f, 1.0f);
235 const Rgb Rgb::BLACK(0.0f, 0.0f, 0.0f);
236 
238 {
239  return rgb2hsv(*this);
240 }
241 
243 {
244  return Rgba::fromRgb(*this);
245 }
246 
247 Rgba Rgb::toRgba(const float a) const
248 {
249  return Rgba::fromRgb(*this, a);
250 }
251 
252 Rgb Rgb::fromHsv(const Hsv &hsv)
253 {
254  return hsv2rgb(hsv);
255 }
256 
258  : h(0.0f)
259  , s(0.0f)
260  , v(0.0f)
261 {
262 }
263 
264 Hsv::Hsv(const float h, const float s, const float v)
265  : h(h)
266  , s(s)
267  , v(v)
268 {
269 }
270 
272 {
273  return hsv2rgb(*this);
274 }
275 
277 {
278  return toRgb().toRgba();
279 }
280 
281 Rgba Hsv::toRgba(const float a) const
282 {
283  return toRgb().toRgba();
284 }
285 
286 Hsv Hsv::fromRgb(const Rgb &rgb)
287 {
288  return rgb2hsv(rgb);
289 }
290 
291 Hsv astra_ros::indexColor(const std::size_t i)
292 {
293  return Hsv(goldenHue(i), 1.0f, 1.0f);
294 }
astra_ros::Rgb
Definition: color.hpp:60
min
int min(int a, int b)
astra_ros::indexColor
Hsv indexColor(const std::size_t i)
Definition: color.cpp:291
astra_ros::Rgba::a
float a
Definition: color.hpp:43
astra_ros::Rgb::fromHsv
static Rgb fromHsv(const Hsv &hsv)
Definition: color.cpp:252
astra_ros::Rgb::WHITE
static const Rgb WHITE
Definition: color.hpp:78
s
XmlRpcServer s
astra_ros::Hsv::fromRgb
static Hsv fromRgb(const Rgb &rgb)
Definition: color.cpp:286
astra_ros::Rgb::g
float g
Definition: color.hpp:71
astra_ros::Rgb::toRgba
Rgba toRgba() const
Definition: color.cpp:242
astra_ros::Rgb::r
float r
Definition: color.hpp:69
astra_ros::Hsv::toRgba
Rgba toRgba() const
Definition: color.cpp:276
astra_ros::Hsv
Definition: color.hpp:89
f
f
astra_ros::Rgba::fromRgb
static Rgba fromRgb(const Rgb &rgb)
Definition: color.cpp:182
astra_ros::Rgba::RED
static const Rgba RED
Definition: color.hpp:45
astra_ros::Rgba::g
float g
Definition: color.hpp:39
astra_ros::Hsv::h
float h
Definition: color.hpp:95
astra_ros::Rgba::GREEN
static const Rgba GREEN
Definition: color.hpp:46
astra_ros::Rgb::BLUE
static const Rgb BLUE
Definition: color.hpp:77
astra_ros::Rgba::Rgba
Rgba()
Definition: color.cpp:150
astra_ros::Rgba
A RGB color with alpha component.
Definition: color.hpp:18
astra_ros::Rgba::fromHsv
static Rgba fromHsv(const Hsv &hsv)
Definition: color.cpp:197
astra_ros::Hsv::v
float v
Definition: color.hpp:99
astra_ros::Rgba::BLUE
static const Rgba BLUE
Definition: color.hpp:47
astra_ros::Hsv::toRgb
Rgb toRgb() const
Definition: color.cpp:271
astra_ros::Rgb::RED
static const Rgb RED
Definition: color.hpp:75
astra_ros::Rgb::Rgb
Rgb()
Definition: color.cpp:202
astra_ros::Hsv::Hsv
Hsv()
Definition: color.cpp:257
astra_ros::Rgba::r
float r
Definition: color.hpp:37
color.hpp
astra_ros::Rgba::WHITE
static const Rgba WHITE
Definition: color.hpp:48
astra_ros::Rgb::b
float b
Definition: color.hpp:73
astra_ros::Rgba::BLACK
static const Rgba BLACK
Definition: color.hpp:49
astra_ros::Hsv::s
float s
Definition: color.hpp:97
astra_ros::Rgb::toHsv
Hsv toHsv() const
Definition: color.cpp:237
astra_ros::Rgb::GREEN
static const Rgb GREEN
Definition: color.hpp:76
astra_ros::Rgb::BLACK
static const Rgb BLACK
Definition: color.hpp:79
astra_ros::Rgba::b
float b
Definition: color.hpp:41
astra_ros
Definition: Device.hpp:14


astra_ros
Author(s): Braden McDorman
autogenerated on Wed Mar 2 2022 00:53:06