Eclipse SUMO - Simulation of Urban MObility
RGBColor.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // A RGB-color definition
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <cmath>
27 #include <cassert>
28 #include <string>
29 #include <sstream>
32 #include <utils/common/ToString.h>
35 #include <utils/common/StdDefs.h>
36 #include "RGBColor.h"
37 
38 
39 // ===========================================================================
40 // static member definitions
41 // ===========================================================================
42 const RGBColor RGBColor::RED = RGBColor(255, 0, 0, 255);
43 const RGBColor RGBColor::GREEN = RGBColor(0, 255, 0, 255);
44 const RGBColor RGBColor::BLUE = RGBColor(0, 0, 255, 255);
45 const RGBColor RGBColor::YELLOW = RGBColor(255, 255, 0, 255);
46 const RGBColor RGBColor::CYAN = RGBColor(0, 255, 255, 255);
47 const RGBColor RGBColor::MAGENTA = RGBColor(255, 0, 255, 255);
48 const RGBColor RGBColor::ORANGE = RGBColor(255, 128, 0, 255);
49 const RGBColor RGBColor::WHITE = RGBColor(255, 255, 255, 255);
50 const RGBColor RGBColor::BLACK = RGBColor(0, 0, 0, 255);
51 const RGBColor RGBColor::GREY = RGBColor(128, 128, 128, 255);
52 const RGBColor RGBColor::INVISIBLE = RGBColor(0, 0, 0, 0);
53 
56 
57 // random colors do not affect the simulation. No initialization is necessary
58 std::mt19937 RGBColor::myRNG;
59 
60 // ===========================================================================
61 // method definitions
62 // ===========================================================================
64  : myRed(0), myGreen(0), myBlue(0), myAlpha(0) {}
65 
66 
67 RGBColor::RGBColor(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
68  : myRed(red), myGreen(green), myBlue(blue), myAlpha(alpha) {}
69 
70 
72  : myRed(col.myRed), myGreen(col.myGreen), myBlue(col.myBlue), myAlpha(col.myAlpha) {}
73 
74 
76 
77 
78 void
79 RGBColor::set(unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
80  myRed = r;
81  myGreen = g;
82  myBlue = b;
83  myAlpha = a;
84 }
85 
86 
87 std::ostream&
88 operator<<(std::ostream& os, const RGBColor& col) {
89  if (col == RGBColor::RED) {
90  return os << "red";
91  }
92  if (col == RGBColor::GREEN) {
93  return os << "green";
94  }
95  if (col == RGBColor::BLUE) {
96  return os << "blue";
97  }
98  if (col == RGBColor::YELLOW) {
99  return os << "yellow";
100  }
101  if (col == RGBColor::CYAN) {
102  return os << "cyan";
103  }
104  if (col == RGBColor::MAGENTA) {
105  return os << "magenta";
106  }
107  if (col == RGBColor::ORANGE) {
108  return os << "orange";
109  }
110  if (col == RGBColor::WHITE) {
111  return os << "white";
112  }
113  if (col == RGBColor::BLACK) {
114  return os << "black";
115  }
116  if (col == RGBColor::GREY) {
117  return os << "grey";
118  }
119  os << static_cast<int>(col.myRed) << ","
120  << static_cast<int>(col.myGreen) << ","
121  << static_cast<int>(col.myBlue);
122  if (col.myAlpha < 255) {
123  os << "," << static_cast<int>(col.myAlpha);
124  }
125  return os;
126 }
127 
128 
129 bool
131  return myRed == c.myRed && myGreen == c.myGreen && myBlue == c.myBlue && myAlpha == c.myAlpha;
132 }
133 
134 
135 bool
137  return myRed != c.myRed || myGreen != c.myGreen || myBlue != c.myBlue || myAlpha != c.myAlpha;
138 }
139 
140 
141 RGBColor
143  // obtain inverse colors
144  const unsigned char r = (unsigned char)(255 - (int)myRed);
145  const unsigned char g = (unsigned char)(255 - (int)myGreen);
146  const unsigned char b = (unsigned char)(255 - (int)myBlue);
147  // return inverted RBColor
148  return RGBColor(r, g, b, myAlpha);
149 }
150 
151 
152 RGBColor
153 RGBColor::changedBrightness(int change, int toChange) const {
154  const unsigned char red = (unsigned char)(MIN2(MAX2(myRed + change, 0), 255));
155  const unsigned char blue = (unsigned char)(MIN2(MAX2(myBlue + change, 0), 255));
156  const unsigned char green = (unsigned char)(MIN2(MAX2(myGreen + change, 0), 255));
157  int changed = ((int)red - (int)myRed) + ((int)blue - (int)myBlue) + ((int)green - (int)myGreen);
158  const RGBColor result(red, green, blue, myAlpha);
159  if (changed == toChange * change) {
160  return result;
161  } else if (changed == 0) {
162  return result;
163  } else {
164  const int maxedColors = (red != myRed + change ? 1 : 0) + (blue != myBlue + change ? 1 : 0) + (green != myGreen + change ? 1 : 0);
165  if (maxedColors == 3) {
166  return result;
167  } else {
168  const int toChangeNext = 3 - maxedColors;
169  return result.changedBrightness((int)((toChange * change - changed) / toChangeNext), toChangeNext);
170  }
171  }
172 }
173 
174 
175 RGBColor
176 RGBColor::parseColor(std::string coldef) {
177  std::transform(coldef.begin(), coldef.end(), coldef.begin(), tolower);
178  if (coldef == "red") {
179  return RED;
180  }
181  if (coldef == "green") {
182  return GREEN;
183  }
184  if (coldef == "blue") {
185  return BLUE;
186  }
187  if (coldef == "yellow") {
188  return YELLOW;
189  }
190  if (coldef == "cyan") {
191  return CYAN;
192  }
193  if (coldef == "magenta") {
194  return MAGENTA;
195  }
196  if (coldef == "orange") {
197  return ORANGE;
198  }
199  if (coldef == "white") {
200  return WHITE;
201  }
202  if (coldef == "black") {
203  return BLACK;
204  }
205  if (coldef == "grey" || coldef == "gray") {
206  return GREY;
207  }
208  unsigned char r = 0;
209  unsigned char g = 0;
210  unsigned char b = 0;
211  unsigned char a = 255;
212  if (coldef[0] == '#') {
213  const int coldesc = StringUtils::hexToInt(coldef);
214  if (coldef.length() == 7) {
215  r = static_cast<unsigned char>((coldesc & 0xFF0000) >> 16);
216  g = static_cast<unsigned char>((coldesc & 0x00FF00) >> 8);
217  b = coldesc & 0xFF;
218  } else if (coldef.length() == 9) {
219  r = static_cast<unsigned char>((coldesc & 0xFF000000) >> 24);
220  g = static_cast<unsigned char>((coldesc & 0x00FF0000) >> 16);
221  b = static_cast<unsigned char>((coldesc & 0x0000FF00) >> 8);
222  a = coldesc & 0xFF;
223  } else {
224  throw EmptyData();
225  }
226  } else {
227  std::vector<std::string> st = StringTokenizer(coldef, ",").getVector();
228  if (st.size() == 3 || st.size() == 4) {
229  try {
230  r = static_cast<unsigned char>(StringUtils::toInt(st[0]));
231  g = static_cast<unsigned char>(StringUtils::toInt(st[1]));
232  b = static_cast<unsigned char>(StringUtils::toInt(st[2]));
233  if (st.size() == 4) {
234  a = static_cast<unsigned char>(StringUtils::toInt(st[3]));
235  }
236  if (r <= 1 && g <= 1 && b <= 1 && (st.size() == 3 || a <= 1)) {
237  throw NumberFormatException("(color component) " + coldef);
238  }
239  } catch (NumberFormatException&) {
240  r = static_cast<unsigned char>(StringUtils::toDouble(st[0]) * 255. + 0.5);
241  g = static_cast<unsigned char>(StringUtils::toDouble(st[1]) * 255. + 0.5);
242  b = static_cast<unsigned char>(StringUtils::toDouble(st[2]) * 255. + 0.5);
243  if (st.size() == 4) {
244  a = static_cast<unsigned char>(StringUtils::toDouble(st[3]) * 255. + 0.5);
245  }
246  }
247  } else {
248  throw EmptyData();
249  }
250  }
251  return RGBColor(r, g, b, a);
252 }
253 
254 
255 RGBColor
257  const std::string& coldef, const std::string& objecttype,
258  const char* objectid, bool report, bool& ok) {
259  UNUSED_PARAMETER(report);
260  try {
261  return parseColor(coldef);
262  } catch (NumberFormatException&) {
263  } catch (EmptyData&) {
264  }
265  ok = false;
266  std::ostringstream oss;
267  oss << "Attribute 'color' in definition of ";
268  if (objectid == nullptr) {
269  oss << "a ";
270  }
271  oss << objecttype;
272  if (objectid != nullptr) {
273  oss << " '" << objectid << "'";
274  }
275  oss << " is not a valid color.";
276  WRITE_ERROR(oss.str());
277  return RGBColor();
278 }
279 
280 
281 RGBColor
282 RGBColor::interpolate(const RGBColor& minColor, const RGBColor& maxColor, double weight) {
283  if (weight < 0) {
284  weight = 0;
285  }
286  if (weight > 1) {
287  weight = 1;
288  }
289  const unsigned char r = (unsigned char)((int)minColor.myRed + (((int)maxColor.myRed - (int)minColor.myRed) * weight));
290  const unsigned char g = (unsigned char)((int)minColor.myGreen + (((int)maxColor.myGreen - (int)minColor.myGreen) * weight));
291  const unsigned char b = (unsigned char)((int)minColor.myBlue + (((int)maxColor.myBlue - (int)minColor.myBlue) * weight));
292  const unsigned char a = (unsigned char)((int)minColor.myAlpha + (((int)maxColor.myAlpha - (int)minColor.myAlpha) * weight));
293  return RGBColor(r, g, b, a);
294 }
295 
296 
297 RGBColor
298 RGBColor::fromHSV(double h, double s, double v) {
299  h /= 60.;
300  const int i = int(floor(h));
301  double f = h - i;
302  if (i % 2 == 0) {
303  f = 1. - f;
304  }
305  const unsigned char m = static_cast<unsigned char>(v * (1 - s) * 255. + 0.5);
306  const unsigned char n = static_cast<unsigned char>(v * (1 - s * f) * 255. + 0.5);
307  const unsigned char vv = static_cast<unsigned char>(v * 255. + 0.5);
308  switch (i) {
309  case 6:
310  case 0:
311  return RGBColor(vv, n, m, 255);
312  case 1:
313  return RGBColor(n, vv, m, 255);
314  case 2:
315  return RGBColor(m, vv, n, 255);
316  case 3:
317  return RGBColor(m, n, vv, 255);
318  case 4:
319  return RGBColor(n, m, vv, 255);
320  case 5:
321  return RGBColor(vv, m, n, 255);
322  }
323  return RGBColor(255, 255, 255, 255);
324 }
325 
326 RGBColor
327 RGBColor::randomHue(double s, double v) {
328  return fromHSV(RandHelper::rand(360, &myRNG), s, v);
329 }
330 
331 /****************************************************************************/
332 
RGBColor::GREY
static const RGBColor GREY
Definition: RGBColor.h:198
RGBColor::myAlpha
unsigned char myAlpha
Definition: RGBColor.h:210
UNUSED_PARAMETER
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:31
RGBColor::DEFAULT_COLOR
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:203
ToString.h
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:73
RGBColor::INVISIBLE
static const RGBColor INVISIBLE
Definition: RGBColor.h:199
operator<<
std::ostream & operator<<(std::ostream &os, const RGBColor &col)
Definition: RGBColor.cpp:88
RGBColor::myGreen
unsigned char myGreen
Definition: RGBColor.h:210
RGBColor::BLACK
static const RGBColor BLACK
Definition: RGBColor.h:197
RGBColor::operator==
bool operator==(const RGBColor &c) const
Definition: RGBColor.cpp:130
StringUtils::toDouble
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
Definition: StringUtils.cpp:345
MsgHandler.h
RGBColor::YELLOW
static const RGBColor YELLOW
Definition: RGBColor.h:192
RGBColor::CYAN
static const RGBColor CYAN
Definition: RGBColor.h:193
EmptyData
Definition: UtilExceptions.h:68
RGBColor::myRed
unsigned char myRed
The color amounts.
Definition: RGBColor.h:210
RGBColor::red
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.h:61
RGBColor.h
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:79
RGBColor::RGBColor
RGBColor()
Constructor.
Definition: RGBColor.cpp:63
RGBColor::interpolate
static RGBColor interpolate(const RGBColor &minColor, const RGBColor &maxColor, double weight)
Interpolates between two colors.
Definition: RGBColor.cpp:282
NumberFormatException
Definition: UtilExceptions.h:95
RGBColor
Definition: RGBColor.h:39
RandHelper::rand
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:53
RGBColor::MAGENTA
static const RGBColor MAGENTA
Definition: RGBColor.h:194
RGBColor::DEFAULT_COLOR_STRING
static const std::string DEFAULT_COLOR_STRING
The string description of the default color.
Definition: RGBColor.h:206
RGBColor::ORANGE
static const RGBColor ORANGE
Definition: RGBColor.h:195
RGBColor::myRNG
static std::mt19937 myRNG
A random number generator to generate random colors independent of other randomness.
Definition: RGBColor.h:213
StringTokenizer
Definition: StringTokenizer.h:61
RGBColor::parseColor
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition: RGBColor.cpp:176
RGBColor::BLUE
static const RGBColor BLUE
Definition: RGBColor.h:191
RGBColor::RED
static const RGBColor RED
named colors
Definition: RGBColor.h:189
RGBColor::randomHue
static RGBColor randomHue(double s=1, double v=1)
Return color with random hue.
Definition: RGBColor.cpp:327
RGBColor::fromHSV
static RGBColor fromHSV(double h, double s, double v)
Converts the given hsv-triplet to rgb, inspired by http://alvyray.com/Papers/CG/hsv2rgb....
Definition: RGBColor.cpp:298
RGBColor::parseColorReporting
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:256
RGBColor::green
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:68
StringUtils::hexToInt
static int hexToInt(const std::string &sData)
converts a string with a hex value into the integer value described by it by calling the char-type co...
Definition: StringUtils.cpp:321
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:47
StringUtils.h
StringUtils::toInt
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
Definition: StringUtils.cpp:278
RGBColor::blue
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.h:75
StringTokenizer::getVector
std::vector< std::string > getVector()
return vector of strings
Definition: StringTokenizer.cpp:191
config.h
RGBColor::invertedColor
RGBColor invertedColor() const
obtain inverted of current RGBColor
Definition: RGBColor.cpp:142
RandHelper.h
StringTokenizer.h
StdDefs.h
RGBColor::GREEN
static const RGBColor GREEN
Definition: RGBColor.h:190
RGBColor::operator!=
bool operator!=(const RGBColor &c) const
Definition: RGBColor.cpp:136
RGBColor::changedBrightness
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition: RGBColor.cpp:153
RGBColor::~RGBColor
~RGBColor()
Destructor.
Definition: RGBColor.cpp:75
WRITE_ERROR
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:283
RGBColor::set
void set(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
assigns new values
Definition: RGBColor.cpp:79
RGBColor::WHITE
static const RGBColor WHITE
Definition: RGBColor.h:196
RGBColor::myBlue
unsigned char myBlue
Definition: RGBColor.h:210