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_g = std::make_tuple(color::green, 21);
42constexpr colorband cband_b = std::make_tuple(color::blue, 34);
43constexpr colorband cband_p = std::make_tuple(color::purple, 33);
44
45
46/**
47 Generate a color band from starting hue and seeds.
48
49 Algorithm is average two known good, where two picked randomly.
50
51 Return type is a vector of generated color_qi types.
52*/
54make_color_band_v1(const colorband& cb, const ushort neededh,
55 auto& spectrum)
56{
57 // Find starting hue and number of samples in the color band.
58 color c = std::get<0>(cb);
59 ushort hn = std::get<1>(cb);
60
61 // Find initial offset.
62 auto itr = std::find(spectrum.begin(), spectrum.end(), c);
63 if (itr == spectrum.end())
64 {
65 string m("collection::make_color_band_v1: color " + to_string(c));
66 m += " not found in spectrum of size ";
67 m += std::to_string(spectrum.size());
68 throw std::runtime_error(m);
69 }
70 const ulong offset = std::distance(spectrum.begin(), itr);
71
72 // Randomness.
73 static std::mt19937_64 rg(std::random_device{}());
74
75 // Setup random picker of sample hues in band.
76 auto disti = std::uniform_int_distribution<>(0, hn - 1);
77
78 // Set up random percentage for combining two colors.
79 auto distr = std::uniform_real_distribution<>(0, 1);
80
81 // Generate new from averaging random samples, cache in return vector.
82 color_qis cband;
83 for (ushort i = 0; i < neededh; ++i)
84 {
85 // New color.
86 ushort o1 = disti(rg);
87 ushort o2 = disti(rg);
88 color_qi c1 = spectrum[offset + o1];
89 color_qi c2 = spectrum[offset + o2];
90
91 // Combine.
92 double c1r = distr(rg);
93 double c2r = 2.0 - c1r;
94 color_qi cgen = combine_color_qi(c1, c1r, c2, c2r);
95 cband.push_back(cgen);
96 }
97
98 return cband;
99}
100
101
102/// Algorightm is HSV generation.
104make_color_band_v2(const colorband& cb, const ushort neededh)
105{
106 // Find starting hue and number of samples in the color band.
107 const auto [ klro, sz ] = cb;
108 color_qi klr = klro;
109
110 // Start with the original colorband.
111 std::set<color_qi> uklrs;
112 for (uint i = 0; i < sz; ++i)
113 {
114 uklrs.insert(klr);
115 klr = next_color(klr);
116 }
117 std::cout << "colorband 1: " << std::to_string(uklrs.size()) << k::newline;
118
119 // Add as necessary.
120 klr = klro;
121 // while (uklrs.size() < neededh)
122 for (uint i = 0; i < neededh; i++)
123 {
124 color_qf hhsv = mutate_color_qf(klr);
125 color_qi klrnu = hhsv.to_color_qi();
126 if (klrnu == klro)
127 {
128 string m("make_color_band_v2:: colorband looping error" + k::newline);
129 m += "starting color: ";
130 m += to_string(klro) + k::newline;
131 m += "starting color band size: ";
132 m += std::to_string(sz) + k::newline;
133 std::cout << m << k::newline;
134 break;
135 }
136 uklrs.insert(klrnu);
137 klr = next_color(klr);
138 std::cout << to_string(klr) << k::tab << to_string(klrnu) << k::newline;
139 }
140 std::cout << "colorband 2: " << std::to_string(uklrs.size()) << k::newline;
141
142 color_qis cband(uklrs.begin(), uklrs.end());
143 std::sort(cband.begin(), cband.end(), svg::color_qf_lt);
144 std::reverse(cband.begin(), cband.end());
145
146 std::cout << "end colorband: " << std::to_string(sz) << k::newline;
147 return cband;
148}
149
150
151/// Forwarding function.
153make_color_band(const colorband& cb, const ushort neededh)
154{
155 return make_color_band_v1(cb, neededh, active_spectrum());
156 //return make_color_band_v2(cb, neededh);
157}
158
159
160/// Flip through color band colors.
161/// @param bandn is the number of colors in the colorband.
162color_qi
163next_in_color_band(const colorband& cb, const ushort bandn = 400)
164{
165 // Generate bands.
166 static color_qis gband_bw = make_color_band_v1(cband_bw, bandn,
168 static color_qis gband_y = make_color_band(cband_y, bandn);
169 static color_qis gband_r = make_color_band(cband_r, bandn);
170 static color_qis gband_g = make_color_band(cband_g, bandn);
171 static color_qis gband_b = make_color_band(cband_b, bandn);
172 static color_qis gband_p = make_color_band(cband_p, bandn);
173 static color_qis gband_o = make_color_band(cband_o, bandn);
174 static color_qis gband_brown = make_color_band(cband_brown, bandn);
175
176 color_qi ret;
177 const color c = std::get<0>(cb);
178 switch (c)
179 {
180 case color::white:
181 ret = gband_bw.back();
182 gband_bw.pop_back();
183 break;
185 ret = gband_y.back();
186 gband_y.pop_back();
187 break;
188 case color::orange:
189 ret = gband_o.back();
190 gband_o.pop_back();
191 break;
193 ret = gband_brown.back();
194 gband_brown.pop_back();
195 break;
196 case color::red:
197 ret = gband_r.back();
198 gband_r.pop_back();
199 break;
200 case color::green:
201 ret = gband_g.back();
202 gband_g.pop_back();
203 break;
204 case color::blue:
205 ret = gband_b.back();
206 gband_b.pop_back();
207 break;
208 case color::purple:
209 ret = gband_p.back();
210 gband_p.pop_back();
211 break;
212 default:
213 string m("next_in_color_band:: error");
214 m += k::newline;
215 m += "color is: ";
216 m += to_string(c);
217 throw std::runtime_error(m);
218 break;
219 }
220 return ret;
221}
222
223} // namespace svg
224
225#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:56
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:58
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_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:57
color_qi next_in_color_band(const colorband &cb, const ushort bandn=400)
Flip through color band colors.
const color_qi to_color_qi()
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.