SUMO - Simulation of Urban MObility
RGBColor.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // A RGB-color definition
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
13 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <cmath>
35 #include <cassert>
36 #include <string>
37 #include <sstream>
39 #include <utils/common/ToString.h>
42 #include <utils/common/StdDefs.h>
43 #include "RGBColor.h"
44 
45 
46 // ===========================================================================
47 // static member definitions
48 // ===========================================================================
49 const RGBColor RGBColor::RED = RGBColor(255, 0, 0, 255);
50 const RGBColor RGBColor::GREEN = RGBColor(0, 255, 0, 255);
51 const RGBColor RGBColor::BLUE = RGBColor(0, 0, 255, 255);
52 const RGBColor RGBColor::YELLOW = RGBColor(255, 255, 0, 255);
53 const RGBColor RGBColor::CYAN = RGBColor(0, 255, 255, 255);
54 const RGBColor RGBColor::MAGENTA = RGBColor(255, 0, 255, 255);
55 const RGBColor RGBColor::ORANGE = RGBColor(255, 128, 0, 255);
56 const RGBColor RGBColor::WHITE = RGBColor(255, 255, 255, 255);
57 const RGBColor RGBColor::BLACK = RGBColor(0, 0, 0, 255);
58 const RGBColor RGBColor::GREY = RGBColor(128, 128, 128, 255);
59 
61 const std::string RGBColor::DEFAULT_COLOR_STRING = toString(RGBColor::DEFAULT_COLOR);
62 
63 
64 // ===========================================================================
65 // method definitions
66 // ===========================================================================
68  : myRed(0), myGreen(0), myBlue(0), myAlpha(0) {}
69 
70 
71 RGBColor::RGBColor(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
72  : myRed(red), myGreen(green), myBlue(blue), myAlpha(alpha) {}
73 
74 
76  : myRed(col.myRed), myGreen(col.myGreen), myBlue(col.myBlue), myAlpha(col.myAlpha) {}
77 
78 
80 
81 
82 void
83 RGBColor::set(unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
84  myRed = r;
85  myGreen = g;
86  myBlue = b;
87  myAlpha = a;
88 }
89 
90 
91 std::ostream&
92 operator<<(std::ostream& os, const RGBColor& col) {
93  if (col == RGBColor::RED) {
94  return os << "red";
95  }
96  if (col == RGBColor::GREEN) {
97  return os << "green";
98  }
99  if (col == RGBColor::BLUE) {
100  return os << "blue";
101  }
102  if (col == RGBColor::YELLOW) {
103  return os << "yellow";
104  }
105  if (col == RGBColor::CYAN) {
106  return os << "cyan";
107  }
108  if (col == RGBColor::MAGENTA) {
109  return os << "magenta";
110  }
111  if (col == RGBColor::ORANGE) {
112  return os << "orange";
113  }
114  if (col == RGBColor::WHITE) {
115  return os << "white";
116  }
117  if (col == RGBColor::BLACK) {
118  return os << "black";
119  }
120  if (col == RGBColor::GREY) {
121  return os << "grey";
122  }
123  os << static_cast<int>(col.myRed) << ","
124  << static_cast<int>(col.myGreen) << ","
125  << static_cast<int>(col.myBlue);
126  if (col.myAlpha < 255) {
127  os << "," << static_cast<int>(col.myAlpha);
128  }
129  return os;
130 }
131 
132 
133 bool
135  return myRed == c.myRed && myGreen == c.myGreen && myBlue == c.myBlue && myAlpha == c.myAlpha;
136 }
137 
138 
139 bool
141  return myRed != c.myRed || myGreen != c.myGreen || myBlue != c.myBlue || myAlpha != c.myAlpha;
142 }
143 
144 
145 RGBColor
147  // obtain inverse colors
148  const unsigned char r = (unsigned char)(255 - (int)myRed);
149  const unsigned char g = (unsigned char)(255 - (int)myGreen);
150  const unsigned char b = (unsigned char)(255 - (int)myBlue);
151  // return inverted RBColor
152  return RGBColor(r, g, b, myAlpha);
153 }
154 
155 
156 RGBColor
157 RGBColor::changedBrightness(int change, int toChange) const {
158  const unsigned char red = (unsigned char)(MIN2(MAX2(myRed + change, 0), 255));
159  const unsigned char blue = (unsigned char)(MIN2(MAX2(myBlue + change, 0), 255));
160  const unsigned char green = (unsigned char)(MIN2(MAX2(myGreen + change, 0), 255));
161  int changed = ((int)red - (int)myRed) + ((int)blue - (int)myBlue) + ((int)green - (int)myGreen);
162  const RGBColor result(red, green, blue, myAlpha);
163  if (changed == toChange * change) {
164  return result;
165  } else if (changed == 0) {
166  return result;
167  } else {
168  const int maxedColors = (red != myRed + change ? 1 : 0) + (blue != myBlue + change ? 1 : 0) + (green != myGreen + change ? 1 : 0);
169  if (maxedColors == 3) {
170  return result;
171  } else {
172  const int toChangeNext = 3 - maxedColors;
173  return result.changedBrightness((int)((toChange * change - changed) / toChangeNext), toChangeNext);
174  }
175  }
176 }
177 
178 
179 RGBColor
180 RGBColor::parseColor(std::string coldef) {
181  std::transform(coldef.begin(), coldef.end(), coldef.begin(), tolower);
182  if (coldef == "red") {
183  return RED;
184  }
185  if (coldef == "green") {
186  return GREEN;
187  }
188  if (coldef == "blue") {
189  return BLUE;
190  }
191  if (coldef == "yellow") {
192  return YELLOW;
193  }
194  if (coldef == "cyan") {
195  return CYAN;
196  }
197  if (coldef == "magenta") {
198  return MAGENTA;
199  }
200  if (coldef == "orange") {
201  return ORANGE;
202  }
203  if (coldef == "white") {
204  return WHITE;
205  }
206  if (coldef == "black") {
207  return BLACK;
208  }
209  if (coldef == "grey" || coldef == "gray") {
210  return GREY;
211  }
212  unsigned char r = 0;
213  unsigned char g = 0;
214  unsigned char b = 0;
215  unsigned char a = 255;
216  if (coldef[0] == '#') {
217  const int coldesc = TplConvert::_hex2int(coldef.c_str());
218  if (coldef.length() == 7) {
219  r = static_cast<unsigned char>((coldesc & 0xFF0000) >> 16);
220  g = static_cast<unsigned char>((coldesc & 0x00FF00) >> 8);
221  b = coldesc & 0xFF;
222  } else if (coldef.length() == 9) {
223  r = static_cast<unsigned char>((coldesc & 0xFF000000) >> 24);
224  g = static_cast<unsigned char>((coldesc & 0x00FF0000) >> 16);
225  b = static_cast<unsigned char>((coldesc & 0x0000FF00) >> 8);
226  a = coldesc & 0xFF;
227  } else {
228  throw EmptyData();
229  }
230  } else {
231  std::vector<std::string> st = StringTokenizer(coldef, ",").getVector();
232  if (st.size() == 3 || st.size() == 4) {
233  try {
234  r = static_cast<unsigned char>(TplConvert::_2int(st[0].c_str()));
235  g = static_cast<unsigned char>(TplConvert::_2int(st[1].c_str()));
236  b = static_cast<unsigned char>(TplConvert::_2int(st[2].c_str()));
237  if (st.size() == 4) {
238  a = static_cast<unsigned char>(TplConvert::_2int(st[3].c_str()));
239  }
240  if (r <= 1 && g <= 1 && b <= 1 && (st.size() == 3 || a <= 1)) {
241  throw NumberFormatException();
242  }
243  } catch (NumberFormatException&) {
244  r = static_cast<unsigned char>(TplConvert::_2double(st[0].c_str()) * 255. + 0.5);
245  g = static_cast<unsigned char>(TplConvert::_2double(st[1].c_str()) * 255. + 0.5);
246  b = static_cast<unsigned char>(TplConvert::_2double(st[2].c_str()) * 255. + 0.5);
247  if (st.size() == 4) {
248  a = static_cast<unsigned char>(TplConvert::_2double(st[3].c_str()) * 255. + 0.5);
249  }
250  }
251  } else {
252  throw EmptyData();
253  }
254  }
255  return RGBColor(r, g, b, a);
256 }
257 
258 
259 RGBColor
261  const std::string& coldef, const std::string& objecttype,
262  const char* objectid, bool report, bool& ok) {
263  UNUSED_PARAMETER(report);
264  try {
265  return parseColor(coldef);
266  } catch (NumberFormatException&) {
267  } catch (EmptyData&) {
268  }
269  ok = false;
270  std::ostringstream oss;
271  oss << "Attribute 'color' in definition of ";
272  if (objectid == 0) {
273  oss << "a ";
274  }
275  oss << objecttype;
276  if (objectid != 0) {
277  oss << " '" << objectid << "'";
278  }
279  oss << " is not a valid color.";
280  WRITE_ERROR(oss.str());
281  return RGBColor();
282 }
283 
284 
285 RGBColor
286 RGBColor::interpolate(const RGBColor& minColor, const RGBColor& maxColor, double weight) {
287  if (weight < 0) {
288  weight = 0;
289  }
290  if (weight > 1) {
291  weight = 1;
292  }
293  const unsigned char r = (unsigned char)((int)minColor.myRed + (((int)maxColor.myRed - (int)minColor.myRed) * weight));
294  const unsigned char g = (unsigned char)((int)minColor.myGreen + (((int)maxColor.myGreen - (int)minColor.myGreen) * weight));
295  const unsigned char b = (unsigned char)((int)minColor.myBlue + (((int)maxColor.myBlue - (int)minColor.myBlue) * weight));
296  const unsigned char a = (unsigned char)((int)minColor.myAlpha + (((int)maxColor.myAlpha - (int)minColor.myAlpha) * weight));
297  return RGBColor(r, g, b, a);
298 }
299 
300 
301 RGBColor
302 RGBColor::fromHSV(double h, double s, double v) {
303  // H is given on [0, 6] or UNDEFINED. S and V are given on [0, 1].
304  // RGB are each returned on [0, 255].
305  //float h = HSV.H, s = HSV.S, v = HSV.V,
306  double f;
307  h /= 60.;
308  int i;
309  //if (h == UNDEFINED) RETURN_RGB(v, v, v);
310  i = int(floor(h));
311  f = float(h - i);
312  if (!(i & 1)) {
313  f = 1 - f; // if i is even
314  }
315  const unsigned char m = static_cast<unsigned char>(v * (1 - s) * 255. + 0.5);
316  const unsigned char n = static_cast<unsigned char>(v * (1 - s * f) * 255. + 0.5);
317  const unsigned char vv = static_cast<unsigned char>(v * 255. + 0.5);
318  switch (i) {
319  case 6:
320  case 0:
321  return RGBColor(vv, n, m, 255);
322  case 1:
323  return RGBColor(n, vv, m, 255);
324  case 2:
325  return RGBColor(m, vv, n, 255);
326  case 3:
327  return RGBColor(m, n, vv, 255);
328  case 4:
329  return RGBColor(n, m, vv, 255);
330  case 5:
331  return RGBColor(vv, m, n, 255);
332  }
333  return RGBColor(255, 255, 255, 255);
334 }
335 
336 
337 /****************************************************************************/
338 
static int _hex2int(const E *const data)
converts a char-type array with a hex value into the integer value described by it ...
Definition: TplConvert.h:177
static const RGBColor BLUE
Definition: RGBColor.h:181
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition: RGBColor.cpp:180
~RGBColor()
Destructor.
Definition: RGBColor.cpp:79
static RGBColor fromHSV(double h, double s, double v)
Converts the given hsv-triplet to rgb.
Definition: RGBColor.cpp:302
static const RGBColor WHITE
Definition: RGBColor.h:186
static RGBColor parseColorReporting(const std::string &coldef, const std::string &objecttype, const char *objectid, bool report, bool &ok)
Parses a color information.
Definition: RGBColor.cpp:260
bool operator==(const RGBColor &c) const
Definition: RGBColor.cpp:134
static const RGBColor ORANGE
Definition: RGBColor.h:185
T MAX2(T a, T b)
Definition: StdDefs.h:74
friend std::ostream & operator<<(std::ostream &os, const RGBColor &col)
Writes the color to the given stream.
Definition: RGBColor.cpp:92
static const RGBColor BLACK
Definition: RGBColor.h:187
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:40
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.h:83
bool operator!=(const RGBColor &c) const
Definition: RGBColor.cpp:140
static const RGBColor GREEN
Definition: RGBColor.h:180
static const RGBColor GREY
Definition: RGBColor.h:188
unsigned char myAlpha
Definition: RGBColor.h:199
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
unsigned char myRed
The color amounts.
Definition: RGBColor.h:199
void set(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
assigns new values
Definition: RGBColor.cpp:83
RGBColor invertedColor() const
obtain inverted of current RGBColor
Definition: RGBColor.cpp:146
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:192
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.h:90
unsigned char myGreen
Definition: RGBColor.h:199
static const RGBColor MAGENTA
Definition: RGBColor.h:184
T MIN2(T a, T b)
Definition: StdDefs.h:68
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition: RGBColor.cpp:157
std::vector< std::string > getVector()
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
static const RGBColor YELLOW
Definition: RGBColor.h:182
static int _2int(const E *const data)
converts a char-type array into the integer value described by it
Definition: TplConvert.h:156
static const RGBColor RED
named colors
Definition: RGBColor.h:179
static const RGBColor CYAN
Definition: RGBColor.h:183
static double _2double(const E *const data)
converts a char-type array into the double value described by it
Definition: TplConvert.h:312
unsigned char myBlue
Definition: RGBColor.h:199
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:76
RGBColor()
Constructor.
Definition: RGBColor.cpp:67
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.h:69
static RGBColor interpolate(const RGBColor &minColor, const RGBColor &maxColor, double weight)
Interpolates between two colors.
Definition: RGBColor.cpp:286
static const std::string DEFAULT_COLOR_STRING
The string description of the default color.
Definition: RGBColor.h:195