| 1 | /* -*- mode: C++; indent-tabs-mode: nil; -*- |
|---|
| 2 | * |
|---|
| 3 | * This file is a part of LEMON, a generic C++ optimization library. |
|---|
| 4 | * |
|---|
| 5 | * Copyright (C) 2003-2009 |
|---|
| 6 | * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
|---|
| 7 | * (Egervary Research Group on Combinatorial Optimization, EGRES). |
|---|
| 8 | * |
|---|
| 9 | * Permission to use, modify and distribute this software is granted |
|---|
| 10 | * provided that this copyright notice appears in all copies. For |
|---|
| 11 | * precise terms see the accompanying LICENSE file. |
|---|
| 12 | * |
|---|
| 13 | * This software is provided "AS IS" with no warranty of any kind, |
|---|
| 14 | * express or implied, and with no claim as to its suitability for any |
|---|
| 15 | * purpose. |
|---|
| 16 | * |
|---|
| 17 | */ |
|---|
| 18 | |
|---|
| 19 | #ifndef LEMON_COLOR_H |
|---|
| 20 | #define LEMON_COLOR_H |
|---|
| 21 | |
|---|
| 22 | #include<vector> |
|---|
| 23 | #include<lemon/math.h> |
|---|
| 24 | #include<lemon/maps.h> |
|---|
| 25 | |
|---|
| 26 | |
|---|
| 27 | ///\ingroup misc |
|---|
| 28 | ///\file |
|---|
| 29 | ///\brief Tools to manage RGB colors. |
|---|
| 30 | |
|---|
| 31 | namespace lemon { |
|---|
| 32 | |
|---|
| 33 | |
|---|
| 34 | /// \addtogroup misc |
|---|
| 35 | /// @{ |
|---|
| 36 | |
|---|
| 37 | ///Data structure representing RGB colors. |
|---|
| 38 | |
|---|
| 39 | ///Data structure representing RGB colors. |
|---|
| 40 | class Color |
|---|
| 41 | { |
|---|
| 42 | double _r,_g,_b; |
|---|
| 43 | public: |
|---|
| 44 | ///Default constructor |
|---|
| 45 | Color() {} |
|---|
| 46 | ///Constructor |
|---|
| 47 | Color(double r,double g,double b) :_r(r),_g(g),_b(b) {}; |
|---|
| 48 | ///Set the red component |
|---|
| 49 | double & red() {return _r;} |
|---|
| 50 | ///Return the red component |
|---|
| 51 | const double & red() const {return _r;} |
|---|
| 52 | ///Set the green component |
|---|
| 53 | double & green() {return _g;} |
|---|
| 54 | ///Return the green component |
|---|
| 55 | const double & green() const {return _g;} |
|---|
| 56 | ///Set the blue component |
|---|
| 57 | double & blue() {return _b;} |
|---|
| 58 | ///Return the blue component |
|---|
| 59 | const double & blue() const {return _b;} |
|---|
| 60 | ///Set the color components |
|---|
| 61 | void set(double r,double g,double b) { _r=r;_g=g;_b=b; }; |
|---|
| 62 | }; |
|---|
| 63 | |
|---|
| 64 | /// White color constant |
|---|
| 65 | extern const Color WHITE; |
|---|
| 66 | /// Black color constant |
|---|
| 67 | extern const Color BLACK; |
|---|
| 68 | /// Red color constant |
|---|
| 69 | extern const Color RED; |
|---|
| 70 | /// Green color constant |
|---|
| 71 | extern const Color GREEN; |
|---|
| 72 | /// Blue color constant |
|---|
| 73 | extern const Color BLUE; |
|---|
| 74 | /// Yellow color constant |
|---|
| 75 | extern const Color YELLOW; |
|---|
| 76 | /// Magenta color constant |
|---|
| 77 | extern const Color MAGENTA; |
|---|
| 78 | /// Cyan color constant |
|---|
| 79 | extern const Color CYAN; |
|---|
| 80 | /// Grey color constant |
|---|
| 81 | extern const Color GREY; |
|---|
| 82 | /// Dark red color constant |
|---|
| 83 | extern const Color DARK_RED; |
|---|
| 84 | /// Dark green color constant |
|---|
| 85 | extern const Color DARK_GREEN; |
|---|
| 86 | /// Drak blue color constant |
|---|
| 87 | extern const Color DARK_BLUE; |
|---|
| 88 | /// Dark yellow color constant |
|---|
| 89 | extern const Color DARK_YELLOW; |
|---|
| 90 | /// Dark magenta color constant |
|---|
| 91 | extern const Color DARK_MAGENTA; |
|---|
| 92 | /// Dark cyan color constant |
|---|
| 93 | extern const Color DARK_CYAN; |
|---|
| 94 | |
|---|
| 95 | ///Map <tt>int</tt>s to different <tt>Color</tt>s |
|---|
| 96 | |
|---|
| 97 | ///This map assigns one of the predefined \ref Color "Color"s to |
|---|
| 98 | ///each <tt>int</tt>. It is possible to change the colors as well as |
|---|
| 99 | ///their number. The integer range is cyclically mapped to the |
|---|
| 100 | ///provided set of colors. |
|---|
| 101 | /// |
|---|
| 102 | ///This is a true \ref concepts::ReferenceMap "reference map", so |
|---|
| 103 | ///you can also change the actual colors. |
|---|
| 104 | |
|---|
| 105 | class Palette : public MapBase<int,Color> |
|---|
| 106 | { |
|---|
| 107 | std::vector<Color> colors; |
|---|
| 108 | public: |
|---|
| 109 | ///Constructor |
|---|
| 110 | |
|---|
| 111 | ///Constructor. |
|---|
| 112 | ///\param have_white Indicates whether white is among the |
|---|
| 113 | ///provided initial colors (\c true) or not (\c false). If it is true, |
|---|
| 114 | ///white will be assigned to \c 0. |
|---|
| 115 | ///\param num The number of the allocated colors. If it is \c -1, |
|---|
| 116 | ///the default color configuration is set up (26 color plus optionaly the |
|---|
| 117 | ///white). If \c num is less then 26/27 then the default color |
|---|
| 118 | ///list is cut. Otherwise the color list is filled repeatedly with |
|---|
| 119 | ///the default color list. (The colors can be changed later on.) |
|---|
| 120 | Palette(bool have_white=false,int num=-1) |
|---|
| 121 | { |
|---|
| 122 | if (num==0) return; |
|---|
| 123 | do { |
|---|
| 124 | if(have_white) colors.push_back(Color(1,1,1)); |
|---|
| 125 | |
|---|
| 126 | colors.push_back(Color(0,0,0)); |
|---|
| 127 | colors.push_back(Color(1,0,0)); |
|---|
| 128 | colors.push_back(Color(0,1,0)); |
|---|
| 129 | colors.push_back(Color(0,0,1)); |
|---|
| 130 | colors.push_back(Color(1,1,0)); |
|---|
| 131 | colors.push_back(Color(1,0,1)); |
|---|
| 132 | colors.push_back(Color(0,1,1)); |
|---|
| 133 | |
|---|
| 134 | colors.push_back(Color(.5,0,0)); |
|---|
| 135 | colors.push_back(Color(0,.5,0)); |
|---|
| 136 | colors.push_back(Color(0,0,.5)); |
|---|
| 137 | colors.push_back(Color(.5,.5,0)); |
|---|
| 138 | colors.push_back(Color(.5,0,.5)); |
|---|
| 139 | colors.push_back(Color(0,.5,.5)); |
|---|
| 140 | |
|---|
| 141 | colors.push_back(Color(.5,.5,.5)); |
|---|
| 142 | colors.push_back(Color(1,.5,.5)); |
|---|
| 143 | colors.push_back(Color(.5,1,.5)); |
|---|
| 144 | colors.push_back(Color(.5,.5,1)); |
|---|
| 145 | colors.push_back(Color(1,1,.5)); |
|---|
| 146 | colors.push_back(Color(1,.5,1)); |
|---|
| 147 | colors.push_back(Color(.5,1,1)); |
|---|
| 148 | |
|---|
| 149 | colors.push_back(Color(1,.5,0)); |
|---|
| 150 | colors.push_back(Color(.5,1,0)); |
|---|
| 151 | colors.push_back(Color(1,0,.5)); |
|---|
| 152 | colors.push_back(Color(0,1,.5)); |
|---|
| 153 | colors.push_back(Color(0,.5,1)); |
|---|
| 154 | colors.push_back(Color(.5,0,1)); |
|---|
| 155 | } while(int(colors.size())<num); |
|---|
| 156 | if(num>=0) colors.resize(num); |
|---|
| 157 | } |
|---|
| 158 | ///\e |
|---|
| 159 | Color &operator[](int i) |
|---|
| 160 | { |
|---|
| 161 | return colors[i%colors.size()]; |
|---|
| 162 | } |
|---|
| 163 | ///\e |
|---|
| 164 | const Color &operator[](int i) const |
|---|
| 165 | { |
|---|
| 166 | return colors[i%colors.size()]; |
|---|
| 167 | } |
|---|
| 168 | ///\e |
|---|
| 169 | void set(int i,const Color &c) |
|---|
| 170 | { |
|---|
| 171 | colors[i%colors.size()]=c; |
|---|
| 172 | } |
|---|
| 173 | ///Adds a new color to the end of the color list. |
|---|
| 174 | void add(const Color &c) |
|---|
| 175 | { |
|---|
| 176 | colors.push_back(c); |
|---|
| 177 | } |
|---|
| 178 | |
|---|
| 179 | ///Sets the number of the existing colors. |
|---|
| 180 | void resize(int s) { colors.resize(s);} |
|---|
| 181 | ///Returns the number of the existing colors. |
|---|
| 182 | int size() const { return int(colors.size());} |
|---|
| 183 | }; |
|---|
| 184 | |
|---|
| 185 | ///Returns a visibly distinct \ref Color |
|---|
| 186 | |
|---|
| 187 | ///Returns a \ref Color which is as different from the given parameter |
|---|
| 188 | ///as it is possible. |
|---|
| 189 | inline Color distantColor(const Color &c) |
|---|
| 190 | { |
|---|
| 191 | return Color(c.red()<.5?1:0,c.green()<.5?1:0,c.blue()<.5?1:0); |
|---|
| 192 | } |
|---|
| 193 | ///Returns black for light colors and white for the dark ones. |
|---|
| 194 | |
|---|
| 195 | ///Returns black for light colors and white for the dark ones. |
|---|
| 196 | inline Color distantBW(const Color &c){ |
|---|
| 197 | return (.2125*c.red()+.7154*c.green()+.0721*c.blue())<.5 ? WHITE : BLACK; |
|---|
| 198 | } |
|---|
| 199 | |
|---|
| 200 | /// @} |
|---|
| 201 | |
|---|
| 202 | } //END OF NAMESPACE LEMON |
|---|
| 203 | |
|---|
| 204 | #endif // LEMON_COLOR_H |
|---|