1 /// The MIT License (MIT)
2 ///
3 /// Copyright (c) 2016 Andrew J Copland
4 ///
5 /// Permission is hereby granted, free of charge, to any person obtaining a copy
6 /// of this software and associated documentation files (the "Software"), to deal
7 /// in the Software without restriction, including without limitation the rights
8 /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 /// copies of the Software, and to permit persons to whom the Software is
10 /// furnished to do so, subject to the following conditions:
11 ///
12 /// The above copyright notice and this permission notice shall be included in all
13 /// copies or substantial portions of the Software.
14 ///
15 /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 /// SOFTWARE.
22 
23 #pragma once
24 
25 #ifndef _RANDOM_COLOR_H_
26 #define _RANDOM_COLOR_H_
27 
28 // Andrew Copland (2016/03/10 )This is a port of a port! Done under the MIT license (see ^^^Above^^^).
29 // Originally pointed out to me by RobN in a forum thread (http://pioneerspacesim.net/forum/viewtopic.php?f=3&t=221)
30 // I was deterred by A) not knowing any javascript, B) the more I saw of it the more I hated it.
31 // Then I noticed the C# port by Nathan Jones (https://github.com/nathanpjones/randomColorSharped) which was a much more logical starting point.
32 // I have included a snippet of his readme below about how he himself came to port it.
33 
34 //randomColorSharped
35 //==================
36 //
37 // This is a port to c# (.NET 4.0) of [randomColor](http://llllll.li/randomColor/), David Merfield's javascript random color generator.
38 // This was ported by [Nathan Jones](http://www.nathanpjones.com/) so that users of the .NET family of languages could enjoy these attractive colors.
39 //
40 // I saw this project linked on [Scott Hanselman's](http://www.hanselman.com/) excellent [Newsletter of Wonderful Things](http://www.hanselman.com/newsletter/)
41 // around the same time a coworker was creating an ad hoc visualization app. As we watched the data appear on screen, we had to squint as some of the colors
42 // were very difficult to make out against the background. This should make things easier to see and will hopefully help others as well.
43 
44 #include "Color.h"
45 #include "Random.h"
46 
47 #include <cstdlib>
48 #include <map>
49 #include <vector>
50 
51 namespace RandomColorGenerator {
52 	// Represents a range using an upper and lower value.
53 	class Range {
54 	public:
55 		int Lower;
56 		int Upper;
57 
Range()58 		Range() {}
Range(int lower,int upper)59 		Range(int lower, int upper)
60 		{
61 			Lower = lower;
62 			Upper = upper;
63 		}
64 
65 		// Gets the lower range for an index of 0 and the upper for an index of 1.
66 		const int &operator[](const size_t index) const
67 		{
68 			if (index == 0)
69 				return Lower;
70 			else
71 				return Upper;
72 		}
73 	};
74 
75 	enum ColorScheme {
76 		// Select randomly from among the other color schemes.
77 		SCHEME_RANDOM = 0,
78 		// Generates only grayscale colors.
79 		SCHEME_MONOCHROME,
80 		// Generates only red colors.
81 		SCHEME_RED,
82 		// Generates only orange colors.
83 		SCHEME_ORANGE,
84 		// Generates only yellow colors.
85 		SCHEME_YELLOW,
86 		// Generates only green colors.
87 		SCHEME_GREEN,
88 		// Generates only blue colors.
89 		SCHEME_BLUE,
90 		// Generates only purple colors.
91 		SCHEME_PURPLE,
92 		// Generates only pink colors.
93 		SCHEME_PINK
94 	};
95 
96 	enum Luminosity {
97 		// Select randomly from among the other luminosities.
98 		LUMINOSITY_RANDOM = 0,
99 		// Generate dark colors.
100 		LUMINOSITY_DARK,
101 		// Generate light, pastel colors.
102 		LUMINOSITY_LIGHT,
103 		// Generate vibrant colors.
104 		LUMINOSITY_BRIGHT
105 	};
106 
107 	class Point {
108 	public:
Point()109 		Point() :
110 			x(0),
111 			y(0) {}
Point(int nx,int ny)112 		Point(int nx, int ny) :
113 			x(nx),
114 			y(ny) {}
115 		int x, y;
116 	};
117 
118 	// Generates random numbers.
119 	class RandomColor {
120 	private:
121 		class DefinedColor {
122 		public:
DefinedColor()123 			DefinedColor() {}
124 			Range HueRange;
125 			std::vector<Point> LowerBounds;
126 			Range SaturationRange;
127 			Range BrightnessRange;
128 		};
129 
130 		static std::map<ColorScheme, DefinedColor> ColorDictionary;
131 
132 	public:
133 		RandomColor();
134 
135 		/// Gets a new random color.
136 		/// <param name="scheme">Which color schemed to use when generating the color.</param>
137 		/// <param name="luminosity">The desired luminosity of the color.</param>
138 		static Color GetColor(ColorScheme scheme, Luminosity luminosity);
139 
140 		/// Generates multiple random colors.
141 		/// <param name="scheme">Which color schemed to use when generating the color.</param>
142 		/// <param name="luminosity">The desired luminosity of the color.</param>
143 		/// <param name="count">How many colors to generate</param>
144 		static std::vector<Color> GetColors(Random &rand, ColorScheme scheme, Luminosity luminosity, int count);
145 
146 		static int PickHue(ColorScheme scheme);
147 
148 	private:
149 		static int PickSaturation(int hue, Luminosity luminosity, ColorScheme scheme);
150 
151 		static int PickBrightness(int H, int S, Luminosity luminosity);
152 
153 		static int GetMinimumBrightness(int H, int S);
154 
155 		static Range GetHueRange(ColorScheme colorInput);
156 
157 		static DefinedColor GetColorInfo(int hue);
158 
159 		static int RandomWithin(Range range);
160 		static int RandomWithin(int lower, int upper);
161 
162 		static void DefineColor(ColorScheme scheme, Point hueRange, const Point *lowerBounds, const size_t lbCount);
163 
164 		static void LoadColorBounds();
165 
166 	public:
167 		// Converts hue, saturation, and lightness to a color.
168 		static Color HsvToColor(int hue, int saturation, double value);
169 	};
170 } // namespace RandomColorGenerator
171 
172 #endif // _RANDOM_COLOR_H_
173