izzi
SVG SUBSET C++ API
Loading...
Searching...
No Matches
a60-svg-color-band.h
Go to the documentation of this file.
1// svg color bands-*- mode: C++ -*-
2
3// alpha60
4// bittorrent x scrape x data + analytics
5
6// Copyright (c) 2024-2025, Benjamin De Kosnik <b.dekosnik@gmail.com>
7
8// This file is part of the alpha60 library. This library is free
9// software; you can redistribute it and/or modify it under the terms
10// of the GNU General Public License as published by the Free Software
11// Foundation; either version 3, or (at your option) any later
12// version.
13
14// This library is distributed in the hope that it will be useful, but
15// WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17// General Public License for more details.
18
19#ifndef MiL_SVG_COLOR_BAND_H
20#define MiL_SVG_COLOR_BAND_H 1
21
22//#include "a60-svg-color-palette.h"
23#include <iostream>
24
25
26namespace svg {
27
28
29/// Specific regions of spectrum as bands of color.
30/// Each band has a starting hue and a number of known good samples.
31/// This is then used to seed a generator that computes more of similar hues.
32using colorband = std::tuple<color, ushort>;
33
34/// Izzi palette-specific offsets for colorbands.
35constexpr colorband cband_bw = std::make_tuple(color::white, 2);
36constexpr colorband cband_gray = std::make_tuple(color::white, 16);
37constexpr colorband cband_brown = std::make_tuple(color::duboisbrown5, 7);
38constexpr colorband cband_r = std::make_tuple(color::red, 17);
39constexpr colorband cband_o = std::make_tuple(color::orange, 10);
40constexpr colorband cband_y = std::make_tuple(color::hellayellow, 10);
41constexpr colorband cband_yo = std::make_tuple(color::hellayellow, 20);
42constexpr colorband cband_g = std::make_tuple(color::green, 21);
43constexpr colorband cband_b = std::make_tuple(color::blue, 34);
44constexpr colorband cband_p = std::make_tuple(color::purple, 33);
45
46
47/**
48 Generate a color band from starting hue and seeds.
49
50 Algorithm is average two known good, where two picked randomly.
51
52 Return type is a vector of generated color_qi types.
53*/
55make_color_band_v1(const colorband& cb, const ushort neededh,
56 auto& spectrum)
57{
58 // Find starting hue and number of samples in the color band.
59 color c = std::get<0>(cb);
60 ushort hn = std::get<1>(cb);
61
62 // Find initial offset.
63 auto itr = std::find(spectrum.begin(), spectrum.end(), c);
64 if (itr == spectrum.end())
65 {
66 string m("collection::make_color_band_v1: color " + to_string(c));
67 m += " not found in spectrum of size ";
68 m += std::to_string(spectrum.size());
69 throw std::runtime_error(m);
70 }
71 const ulong offset = std::distance(spectrum.begin(), itr);
72
73 // Randomness.
74 static std::mt19937_64 rg(std::random_device{}());
75
76 // Setup random picker of sample hues in band.
77 auto disti = std::uniform_int_distribution<>(0, hn - 1);
78
79 // Set up random percentage for combining two colors.
80 auto distr = std::uniform_real_distribution<>(0, 1);
81
82 // Generate new from averaging random samples, cache in return vector.
83 color_qis cband;
84 for (ushort i = 0; i < neededh; ++i)
85 {
86 // New color.
87 ushort o1 = disti(rg);
88 ushort o2 = disti(rg);
89 color_qi c1 = spectrum[offset + o1];
90 color_qi c2 = spectrum[offset + o2];
91
92 // Combine.
93 double c1r = distr(rg);
94 double c2r = 2.0 - c1r;
95 color_qi cgen = combine_color_qi(c1, c1r, c2, c2r);
96 cband.push_back(cgen);
97 }
98
99 return cband;
100}
101
102
103/// Algorightm is HSV generation.
105make_color_band_v2(const colorband& cb, const ushort neededh)
106{
107 // Find starting hue and number of samples in the color band.
108 const auto [ klro, sz ] = cb;
109 color_qi klr = klro;
110
111 // Start with the original colorband.
112 std::set<color_qi> uklrs;
113 for (uint i = 0; i < sz; ++i)
114 {
115 uklrs.insert(klr);
116 klr = next_color(klr);
117 }
118 std::cout << "colorband 1: " << std::to_string(uklrs.size()) << k::newline;
119
120 // Add as necessary.
121 klr = klro;
122 // while (uklrs.size() < neededh)
123 for (uint i = 0; i < neededh; i++)
124 {
125 color_qf hhsv = mutate_color_qf(klr);
126 color_qi klrnu = hhsv.to_color_qi();
127 if (klrnu == klro)
128 {
129 string m("make_color_band_v2:: colorband looping error" + k::newline);
130 m += "starting color: ";
131 m += to_string(klro) + k::newline;
132 m += "starting color band size: ";
133 m += std::to_string(sz) + k::newline;
134 std::cout << m << k::newline;
135 break;
136 }
137 uklrs.insert(klrnu);
138 klr = next_color(klr);
139 std::cout << to_string(klr) << k::tab << to_string(klrnu) << k::newline;
140 }
141 std::cout << "colorband 2: " << std::to_string(uklrs.size()) << k::newline;
142
143 color_qis cband(uklrs.begin(), uklrs.end());
144 std::sort(cband.begin(), cband.end(), svg::color_qf_lt);
145 std::reverse(cband.begin(), cband.end());
146
147 std::cout << "end colorband: " << std::to_string(sz) << k::newline;
148 return cband;
149}
150
151
152/// Forwarding function.
154make_color_band(const colorband& cb, const ushort neededh)
155{
156 return make_color_band_v1(cb, neededh, active_spectrum());
157 //return make_color_band_v2(cb, neededh);
158}
159
160
161/// Flip through color band colors.
162/// @param bandn is the number of colors in the colorband.
163color_qi
164next_in_color_band(const colorband& cb, const ushort bandn = 400)
165{
166 // Generate bands.
167 static color_qis gband_bw = make_color_band_v1(cband_bw, bandn,
169 static color_qis gband_y = make_color_band(cband_yo, bandn);
170 static color_qis gband_r = make_color_band(cband_r, bandn);
171 static color_qis gband_g = make_color_band(cband_g, bandn);
172 static color_qis gband_b = make_color_band(cband_b, bandn);
173 static color_qis gband_p = make_color_band(cband_p, bandn);
174 static color_qis gband_o = make_color_band(cband_o, bandn);
175 static color_qis gband_brown = make_color_band(cband_brown, bandn);
176
177 color_qi ret;
178 const color c = std::get<0>(cb);
179 switch (c)
180 {
181 case color::white:
182 ret = gband_bw.back();
183 gband_bw.pop_back();
184 break;
186 ret = gband_y.back();
187 gband_y.pop_back();
188 break;
189 case color::orange:
190 ret = gband_o.back();
191 gband_o.pop_back();
192 break;
194 ret = gband_brown.back();
195 gband_brown.pop_back();
196 break;
197 case color::red:
198 ret = gband_r.back();
199 gband_r.pop_back();
200 break;
201 case color::green:
202 ret = gband_g.back();
203 gband_g.pop_back();
204 break;
205 case color::blue:
206 ret = gband_b.back();
207 gband_b.pop_back();
208 break;
209 case color::purple:
210 ret = gband_p.back();
211 gband_p.pop_back();
212 break;
213 default:
214 string m("next_in_color_band:: error");
215 m += k::newline;
216 m += "color is: ";
217 m += to_string(c);
218 throw std::runtime_error(m);
219 break;
220 }
221 return ret;
222}
223
224} // namespace svg
225
226#endif
constexpr colorband cband_b
constexpr colorband cband_y
color
Color enumerated as types.
unsigned short ushort
Base integer type: positive and negative, signed integral value.
Definition a60-svg.h:57
const string to_string(const unit e)
std::tuple< color, ushort > colorband
Specific regions of spectrum as bands of color. Each band has a starting hue and a number of known go...
std::vector< color_qi > color_qis
Types for Color iteration and combinatorics.
color_qi next_color(const color_qi klr)
Loop through color array starting at position c. Iff klr is not found, return color::none as the next...
constexpr colorband cband_gray
unsigned long ulong
Definition a60-svg.h:59
color_qis make_color_band_v2(const colorband &cb, const ushort neededh)
Algorightm is HSV generation.
constexpr colorband cband_g
color_qf mutate_color_qf(const color_qf &k)
Return a variant on saturation/value only.
color_qis make_color_band(const colorband &cb, const ushort neededh)
Forwarding function.
color_qis make_color_band_v1(const colorband &cb, const ushort neededh, auto &spectrum)
auto & active_spectrum(const bool sortbyhuep=false)
Oklab https://bottosson.github.io/posts/oklab/.
constexpr colorband cband_r
constexpr colorband cband_o
constexpr colorband cband_yo
constexpr colorband cband_bw
Izzi palette-specific offsets for colorbands.
static const palette_qi< color_max_size - 4 > izzi_palette
Default colors for izzi.
constexpr colorband cband_brown
constexpr colorband cband_p
color_qi combine_color_qi(const color_qi &a, const double ad, const color_qi &b, const double bd)
bool color_qf_lt(const color_qf &k1, const color_qf &k2)
Forwarding function.
unsigned int uint
Definition a60-svg.h:58
color_qi next_in_color_band(const colorband &cb, const ushort bandn=400)
Flip through color band colors.
color_qi to_color_qi() const
Back to RGB https://www.rapidtables.com/convert/color/hsv-to-rgb.html.
Color quantified as integral RGB components in the range [0,255]. aka like Scalar in OpenCV.