
pixel does not glow when
- glows as brightly as possible, depending on
and
.
will give not gray, but white of different brightness, therefore the parameter
can be called Whiteness - it reflects the degree of "whiteness" of color. With
color is completely determined by Hue, with
pixel color will be white.
convenient to take the maximum value equal
, for example, 48 or 96. This will allow you to conveniently calculate the RGB color, and a value less than 128 will allow you to build a gradient that several times contains a full color circle. On HSV / HSL models
, in MS Paint - 240, in some libraries - 255.
and
multiplication
gives the result lying in the range
.
,
and
gives us
colors, some of which are almost the same, and some are far enough apart ( for fairness, I note that all color models that operate on H are sinning - Mercator could not stretch the three sides of the cube on a cone without distorting the length ). The figure seems scant compared to the 24-bit color in a typical monitor ( 16.7 million unique colors), but it is enough to diversify the LED props, in which earlier and seven colors instead of one were often a pleasant bonus. The color coordinates in this model can be stored in two bytes.
and 96 tones, which gives already 27.6 thousand shades. An example of code with such parameters (model configuration - max_value, max_whiteness, sixth_hue):typedef struct { uint8_t r; uint8_t g; uint8_t b; } RGB_t; typedef struct { uint8_t h; uint8_t s; uint8_t v; } HSV_t; const uint8_t max_whiteness = 15; const uint8_t max_value = 17; const uint8_t sixth_hue = 16; const uint8_t third_hue = sixth_hue * 2; const uint8_t half_hue = sixth_hue * 3; const uint8_t two_thirds_hue = sixth_hue * 4; const uint8_t five_sixths_hue = sixth_hue * 5; const uint8_t full_hue = sixth_hue * 6; inline RGB_t rgb(uint8_t r, uint8_t g, uint8_t b) { return (RGB_t) {r, g, b}; } inline HSV_t hsv(uint8_t h, uint8_t s, uint8_t v) { return (HSV_t) {h, s, v}; } const RGB_t black = {0, 0, 0}; RGB_t hsv2rgb(HSV_t hsv) { if (hsv.v == 0) return black; uint8_t high = hsv.v * max_whiteness;//channel with max value if (hsv.s == 0) return rgb(high, high, high); uint8_t W = max_whiteness - hsv.s; uint8_t low = hsv.v * W;//channel with min value uint8_t rising = low; uint8_t falling = high; uint8_t h_after_sixth = hsv.h % sixth_hue; if (h_after_sixth > 0) {//not at primary color? ok, h_after_sixth = 1..sixth_hue - 1 uint8_t z = hsv.s * uint8_t(hsv.v * h_after_sixth) / sixth_hue; rising += z; falling -= z + 1;//it's never 255, so ok } uint8_t H = hsv.h; while (H >= full_hue) H -= full_hue; if (H < sixth_hue) return rgb(high, rising, low); if (H < third_hue) return rgb(falling, high, low); if (H < half_hue) return rgb(low, high, rising); if (H < two_thirds_hue) return rgb(low, falling, high); if (H < five_sixths_hue) return rgb(rising, low, high); return rgb(high, low, falling); } Source: https://habr.com/ru/post/166317/
All Articles