SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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-2016 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 #ifdef CHECK_MEMORY_LEAKS
46 #include <foreign/nvwa/debug_new.h>
47 #endif // CHECK_MEMORY_LEAKS
48 
49 
50 // ===========================================================================
51 // static member definitions
52 // ===========================================================================
53 const RGBColor RGBColor::RED = RGBColor(255, 0, 0, 255);
54 const RGBColor RGBColor::GREEN = RGBColor(0, 255, 0, 255);
55 const RGBColor RGBColor::BLUE = RGBColor(0, 0, 255, 255);
56 const RGBColor RGBColor::YELLOW = RGBColor(255, 255, 0, 255);
57 const RGBColor RGBColor::CYAN = RGBColor(0, 255, 255, 255);
58 const RGBColor RGBColor::MAGENTA = RGBColor(255, 0, 255, 255);
59 const RGBColor RGBColor::ORANGE = RGBColor(255, 128, 0, 255);
60 const RGBColor RGBColor::WHITE = RGBColor(255, 255, 255, 255);
61 const RGBColor RGBColor::BLACK = RGBColor(0, 0, 0, 255);
62 const RGBColor RGBColor::GREY = RGBColor(128, 128, 128, 255);
63 
65 const std::string RGBColor::DEFAULT_COLOR_STRING = toString(RGBColor::DEFAULT_COLOR);
66 
67 
68 // ===========================================================================
69 // method definitions
70 // ===========================================================================
72  : myRed(0), myGreen(0), myBlue(0), myAlpha(0) {}
73 
74 
75 RGBColor::RGBColor(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
76  : myRed(red), myGreen(green), myBlue(blue), myAlpha(alpha) {}
77 
78 
80  : myRed(col.myRed), myGreen(col.myGreen), myBlue(col.myBlue), myAlpha(col.myAlpha) {}
81 
82 
84 
85 
86 void
87 RGBColor::set(unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
88  myRed = r;
89  myGreen = g;
90  myBlue = b;
91  myAlpha = a;
92 }
93 
94 
95 std::ostream&
96 operator<<(std::ostream& os, const RGBColor& col) {
97  if (col == RGBColor::RED) {
98  return os << "red";
99  }
100  if (col == RGBColor::GREEN) {
101  return os << "green";
102  }
103  if (col == RGBColor::BLUE) {
104  return os << "blue";
105  }
106  if (col == RGBColor::YELLOW) {
107  return os << "yellow";
108  }
109  if (col == RGBColor::CYAN) {
110  return os << "cyan";
111  }
112  if (col == RGBColor::MAGENTA) {
113  return os << "magenta";
114  }
115  if (col == RGBColor::ORANGE) {
116  return os << "orange";
117  }
118  if (col == RGBColor::WHITE) {
119  return os << "white";
120  }
121  if (col == RGBColor::BLACK) {
122  return os << "black";
123  }
124  if (col == RGBColor::GREY) {
125  return os << "grey";
126  }
127  os << static_cast<int>(col.myRed) << ","
128  << static_cast<int>(col.myGreen) << ","
129  << static_cast<int>(col.myBlue);
130  if (col.myAlpha < 255) {
131  os << "," << static_cast<int>(col.myAlpha);
132  }
133  return os;
134 }
135 
136 
137 bool
139  return myRed == c.myRed && myGreen == c.myGreen && myBlue == c.myBlue && myAlpha == c.myAlpha;
140 }
141 
142 
143 bool
145  return myRed != c.myRed || myGreen != c.myGreen || myBlue != c.myBlue || myAlpha != c.myAlpha;
146 }
147 
148 
149 RGBColor
150 RGBColor::changedBrightness(int change, int toChange) const {
151  const unsigned char red = (unsigned char)(MIN2(MAX2(myRed + change, 0), 255));
152  const unsigned char blue = (unsigned char)(MIN2(MAX2(myBlue + change, 0), 255));
153  const unsigned char green = (unsigned char)(MIN2(MAX2(myGreen + change, 0), 255));
154  int changed = ((int)red - (int)myRed) + ((int)blue - (int)myBlue) + ((int)green - (int)myGreen);
155  const RGBColor result(red, green, blue, myAlpha);
156  if (changed == toChange * change) {
157  return result;
158  } else if (changed == 0) {
159  return result;
160  } else {
161  const int maxedColors = (red != myRed + change ? 1 : 0) + (blue != myBlue + change ? 1 : 0) + (green != myGreen + change ? 1 : 0);
162  if (maxedColors == 3) {
163  return result;
164  } else {
165  const int toChangeNext = 3 - maxedColors;
166  return result.changedBrightness((int)((toChange * change - changed) / toChangeNext), toChangeNext);
167  }
168  }
169 }
170 
171 RGBColor
172 RGBColor::parseColor(std::string coldef) {
173  std::transform(coldef.begin(), coldef.end(), coldef.begin(), tolower);
174  if (coldef == "red") {
175  return RED;
176  }
177  if (coldef == "green") {
178  return GREEN;
179  }
180  if (coldef == "blue") {
181  return BLUE;
182  }
183  if (coldef == "yellow") {
184  return YELLOW;
185  }
186  if (coldef == "cyan") {
187  return CYAN;
188  }
189  if (coldef == "magenta") {
190  return MAGENTA;
191  }
192  if (coldef == "orange") {
193  return ORANGE;
194  }
195  if (coldef == "white") {
196  return WHITE;
197  }
198  if (coldef == "black") {
199  return BLACK;
200  }
201  if (coldef == "grey" || coldef == "gray") {
202  return GREY;
203  }
204  unsigned char r = 0;
205  unsigned char g = 0;
206  unsigned char b = 0;
207  unsigned char a = 255;
208  if (coldef[0] == '#') {
209  const int coldesc = TplConvert::_hex2int(coldef.c_str());
210  if (coldef.length() == 7) {
211  r = static_cast<unsigned char>((coldesc & 0xFF0000) >> 16);
212  g = static_cast<unsigned char>((coldesc & 0x00FF00) >> 8);
213  b = coldesc & 0xFF;
214  } else if (coldef.length() == 9) {
215  r = static_cast<unsigned char>((coldesc & 0xFF000000) >> 24);
216  g = static_cast<unsigned char>((coldesc & 0x00FF0000) >> 16);
217  b = static_cast<unsigned char>((coldesc & 0x0000FF00) >> 8);
218  a = coldesc & 0xFF;
219  } else {
220  throw EmptyData();
221  }
222  } else {
223  std::vector<std::string> st = StringTokenizer(coldef, ",").getVector();
224  if (st.size() == 3 || st.size() == 4) {
225  try {
226  r = static_cast<unsigned char>(TplConvert::_2int(st[0].c_str()));
227  g = static_cast<unsigned char>(TplConvert::_2int(st[1].c_str()));
228  b = static_cast<unsigned char>(TplConvert::_2int(st[2].c_str()));
229  if (st.size() == 4) {
230  a = static_cast<unsigned char>(TplConvert::_2int(st[3].c_str()));
231  }
232  if (r <= 1 && g <= 1 && b <= 1 && (st.size() == 3 || a <= 1)) {
233  throw NumberFormatException();
234  }
235  } catch (NumberFormatException&) {
236  r = static_cast<unsigned char>(TplConvert::_2SUMOReal(st[0].c_str()) * 255. + 0.5);
237  g = static_cast<unsigned char>(TplConvert::_2SUMOReal(st[1].c_str()) * 255. + 0.5);
238  b = static_cast<unsigned char>(TplConvert::_2SUMOReal(st[2].c_str()) * 255. + 0.5);
239  if (st.size() == 4) {
240  a = static_cast<unsigned char>(TplConvert::_2SUMOReal(st[3].c_str()) * 255. + 0.5);
241  }
242  }
243  } else {
244  throw EmptyData();
245  }
246  }
247  return RGBColor(r, g, b, a);
248 }
249 
250 
251 RGBColor
253  const std::string& coldef, const std::string& objecttype,
254  const char* objectid, bool report, bool& ok) {
255  UNUSED_PARAMETER(report);
256  try {
257  return parseColor(coldef);
258  } catch (NumberFormatException&) {
259  } catch (EmptyData&) {
260  }
261  ok = false;
262  std::ostringstream oss;
263  oss << "Attribute 'color' in definition of ";
264  if (objectid == 0) {
265  oss << "a ";
266  }
267  oss << objecttype;
268  if (objectid != 0) {
269  oss << " '" << objectid << "'";
270  }
271  oss << " is not a valid color.";
272  WRITE_ERROR(oss.str());
273  return RGBColor();
274 }
275 
276 
277 RGBColor
278 RGBColor::interpolate(const RGBColor& minColor, const RGBColor& maxColor, SUMOReal weight) {
279  if (weight < 0) {
280  weight = 0;
281  }
282  if (weight > 1) {
283  weight = 1;
284  }
285  const unsigned char r = (unsigned char)((int)minColor.myRed + (((int)maxColor.myRed - (int)minColor.myRed) * weight));
286  const unsigned char g = (unsigned char)((int)minColor.myGreen + (((int)maxColor.myGreen - (int)minColor.myGreen) * weight));
287  const unsigned char b = (unsigned char)((int)minColor.myBlue + (((int)maxColor.myBlue - (int)minColor.myBlue) * weight));
288  const unsigned char a = (unsigned char)((int)minColor.myAlpha + (((int)maxColor.myAlpha - (int)minColor.myAlpha) * weight));
289  return RGBColor(r, g, b, a);
290 }
291 
292 
293 RGBColor
295  // H is given on [0, 6] or UNDEFINED. S and V are given on [0, 1].
296  // RGB are each returned on [0, 255].
297  //float h = HSV.H, s = HSV.S, v = HSV.V,
298  SUMOReal f;
299  h /= 60.;
300  int i;
301  //if (h == UNDEFINED) RETURN_RGB(v, v, v);
302  i = int(floor(h));
303  f = float(h - i);
304  if (!(i & 1)) {
305  f = 1 - f; // if i is even
306  }
307  const unsigned char m = static_cast<unsigned char>(v * (1 - s) * 255. + 0.5);
308  const unsigned char n = static_cast<unsigned char>(v * (1 - s * f) * 255. + 0.5);
309  const unsigned char vv = static_cast<unsigned char>(v * 255. + 0.5);
310  switch (i) {
311  case 6:
312  case 0:
313  return RGBColor(vv, n, m, 255);
314  case 1:
315  return RGBColor(n, vv, m, 255);
316  case 2:
317  return RGBColor(m, vv, n, 255);
318  case 3:
319  return RGBColor(m, n, vv, 255);
320  case 4:
321  return RGBColor(n, m, vv, 255);
322  case 5:
323  return RGBColor(vv, m, n, 255);
324  }
325  return RGBColor(255, 255, 255, 255);
326 }
327 
328 
329 /****************************************************************************/
330 
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:168
static const RGBColor BLUE
Definition: RGBColor.h:191
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition: RGBColor.cpp:172
~RGBColor()
Destructor.
Definition: RGBColor.cpp:83
static RGBColor fromHSV(SUMOReal h, SUMOReal s, SUMOReal v)
Converts the given hsv-triplet to rgb.
Definition: RGBColor.cpp:294
static SUMOReal _2SUMOReal(const E *const data)
converts a char-type array into the SUMOReal value described by it
Definition: TplConvert.h:290
static const RGBColor WHITE
Definition: RGBColor.h:196
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:252
bool operator==(const RGBColor &c) const
Definition: RGBColor.cpp:138
static const RGBColor ORANGE
Definition: RGBColor.h:195
T MAX2(T a, T b)
Definition: StdDefs.h:75
static RGBColor interpolate(const RGBColor &minColor, const RGBColor &maxColor, SUMOReal weight)
Interpolates between two colors.
Definition: RGBColor.cpp:278
static const RGBColor BLACK
Definition: RGBColor.h:197
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.h:91
bool operator!=(const RGBColor &c) const
Definition: RGBColor.cpp:144
static const RGBColor GREEN
Definition: RGBColor.h:190
static const RGBColor GREY
Definition: RGBColor.h:198
unsigned char myAlpha
Definition: RGBColor.h:209
unsigned char myRed
The color amounts.
Definition: RGBColor.h:209
void set(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
assigns new values
Definition: RGBColor.cpp:87
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:200
std::ostream & operator<<(std::ostream &os, const RGBColor &col)
Definition: RGBColor.cpp:96
unsigned char myGreen
Definition: RGBColor.h:209
static const RGBColor MAGENTA
Definition: RGBColor.h:194
T MIN2(T a, T b)
Definition: StdDefs.h:69
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition: RGBColor.cpp:150
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
std::vector< std::string > getVector()
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
static const RGBColor YELLOW
Definition: RGBColor.h:192
static int _2int(const E *const data)
converts a char-type array into the integer value described by it
Definition: TplConvert.h:149
static const RGBColor RED
Definition: RGBColor.h:189
static const RGBColor CYAN
Definition: RGBColor.h:193
unsigned char myBlue
Definition: RGBColor.h:209
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:83
#define SUMOReal
Definition: config.h:214
RGBColor()
Constructor.
Definition: RGBColor.cpp:71
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.h:75
static const std::string DEFAULT_COLOR_STRING
The string description of the default color.
Definition: RGBColor.h:204