summary refs log tree commit diff stats
path: root/palette.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'palette.cpp')
-rw-r--r--palette.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/palette.cpp b/palette.cpp new file mode 100644 index 0000000..4135756 --- /dev/null +++ b/palette.cpp
@@ -0,0 +1,119 @@
1#include "palette.h"
2#include <algorithm>
3
4const std::vector<Magick::ColorRGB> palette::reds = {
5 {"#ff4848"}, {"#ff7575"}, {"#ff8a8a"}, {"#ff9797"}, {"#ffa8a8"}, {"#ffbbbb"}
6};
7
8const std::vector<Magick::ColorRGB> palette::oranges = {
9 {"#ffbf85"}, {"#ffcfa4"}, {"#ffbd82"}, {"#ffc48e"}
10};
11
12const std::vector<Magick::ColorRGB> palette::yellows = {
13 {"#fdfda5"}, {"#eff0ac"}, {"#fef495"}
14};
15
16const std::vector<Magick::ColorRGB> palette::greens = {
17 {"#c6fcb4"}, {"#d4ffa2"}, {"#93eeaa"}
18};
19
20const std::vector<Magick::ColorRGB> palette::blues = {
21 {"#62d0ff"}, {"#62a9ff"}, {"#63e9fc"}, {"#7bcae1"}, {"#92fef9"}
22};
23
24const std::vector<Magick::ColorRGB> palette::purples = {
25 {"#dfb0fe"}, {"#b0a7f1"}, {"#ff86ff"}, {"#ffacec"}, {"#ff86c2"}, {"#ea8dfe"}
26};
27
28palette::palette(std::vector<Magick::Color> foci)
29{
30 if (foci.size() < 1)
31 {
32 throw std::invalid_argument("Must have at least one focus");
33 }
34
35 if (foci.size() < 2)
36 {
37 // Degenerate scenario, but deal with it gracefully.
38 foci.push_back(foci.front());
39 }
40
41 int sections = foci.size() - 1;
42 double sectionSize = 256.0 / static_cast<double>(sections);
43 for (int i=0; i<256; i++)
44 {
45 int section = std::floor(static_cast<double>(i) / sectionSize);
46 double interpolation = (static_cast<double>(i) / sectionSize) - section;
47
48 Magick::ColorHSL interpLeft = foci[section];
49 Magick::ColorHSL interpRight = foci[section+1];
50
51 double newHue;
52 double diff = interpRight.hue() - interpLeft.hue();
53 if (diff < 0)
54 {
55 std::swap(interpLeft, interpRight);
56
57 diff = -diff;
58 interpolation = 1 - interpolation;
59 }
60
61 if (diff > 0.5)
62 {
63 newHue = 1.0 + interpLeft.hue()
64 * (interpolation * (interpRight.hue() - interpLeft.hue() - 1.0));
65
66 if (newHue > 1.0)
67 {
68 newHue -= 1.0;
69 }
70 } else {
71 newHue = interpLeft.hue() + interpolation * diff;
72 }
73
74 Magick::ColorHSL interpolated(
75 newHue,
76 ((1.0 - interpolation) * interpLeft.saturation())
77 + (interpolation * interpRight.saturation()),
78 ((1.0 - interpolation) * interpLeft.luminosity())
79 + (interpolation * interpRight.luminosity()));
80
81 gradient_.push_back(interpolated);
82 }
83}
84
85palette palette::randomPalette(std::mt19937& rng)
86{
87 std::vector<Magick::Color> foci;
88 foci.push_back(reds[
89 std::uniform_int_distribution<int>(0, reds.size()-1)(rng)]);
90 foci.push_back(oranges[
91 std::uniform_int_distribution<int>(0, oranges.size()-1)(rng)]);
92 foci.push_back(yellows[
93 std::uniform_int_distribution<int>(0, yellows.size()-1)(rng)]);
94 foci.push_back(greens[
95 std::uniform_int_distribution<int>(0, greens.size()-1)(rng)]);
96 foci.push_back(blues[
97 std::uniform_int_distribution<int>(0, blues.size()-1)(rng)]);
98 foci.push_back(purples[
99 std::uniform_int_distribution<int>(0, purples.size()-1)(rng)]);
100
101 std::shuffle(std::begin(foci), std::end(foci), rng);
102
103 int origNum = foci.size();
104 int numOfFoci = std::uniform_int_distribution<int>(4, origNum)(rng);
105 for (int i=0; i<(origNum-numOfFoci); i++)
106 {
107 foci.pop_back();
108 }
109
110 foci.push_back(foci[0]);
111
112 return palette(std::move(foci));
113}
114
115Magick::Color palette::getColor(double shade) const
116{
117 int index = std::min((int)floor(shade * 256.0), 255);
118 return gradient_[index];
119}