FastLED 3.10.6
Loading...
Searching...
No Matches
ring_canvas.cpp
Go to the documentation of this file.
1// ring_canvas.cpp - ring geometry and additive drawing.
2#include "ring_canvas.h"
3
4namespace mood_ring {
5
7 RGBf p;
8 p.r = static_cast<float>(c.r) * (1.0f / 255.0f);
9 p.g = static_cast<float>(c.g) * (1.0f / 255.0f);
10 p.b = static_cast<float>(c.b) * (1.0f / 255.0f);
11 return p;
12}
13
14CRGB toCRGB(const RGBf &p) {
15 return CRGB(static_cast<fl::u8>(clampf(p.r, 0.0f, 1.0f) * 255.0f + 0.5f),
16 static_cast<fl::u8>(clampf(p.g, 0.0f, 1.0f) * 255.0f + 0.5f),
17 static_cast<fl::u8>(clampf(p.b, 0.0f, 1.0f) * 255.0f + 0.5f));
18}
19
20float smoothstepf(float e0, float e1, float x) {
21 if (e1 <= e0)
22 return x >= e1 ? 1.0f : 0.0f;
23 float t = clampf((x - e0) / (e1 - e0), 0.0f, 1.0f);
24 return t * t * (3.0f - 2.0f * t);
25}
26
27float wrapTurns(float t) {
28 while (t >= 1.0f)
29 t -= 1.0f;
30 while (t < 0.0f)
31 t += 1.0f;
32 return t;
33}
34
35float ringOffset(float a, float b) {
36 float d = wrapTurns(a) - wrapTurns(b);
37 if (d > 0.5f)
38 d -= 1.0f;
39 if (d <= -0.5f)
40 d += 1.0f;
41 return d;
42}
43
44float ringDistance(float a, float b) {
45 float d = ringOffset(a, b);
46 return d < 0.0f ? -d : d;
47}
48
49float falloff(float distance, float sigma) {
50 if (sigma <= 0.0f)
51 return 0.0f;
52 float t = 1.0f - distance / sigma;
53 if (t <= 0.0f)
54 return 0.0f;
55 if (t >= 1.0f)
56 return 1.0f;
57 return t * t * (3.0f - 2.0f * t);
58}
59
60fl::u32 Xorshift::next() {
61 fl::u32 x = mState;
62 x ^= x << 13;
63 x ^= x >> 17;
64 x ^= x << 5;
65 mState = x;
66 return x;
67}
68
70 return static_cast<float>(next() >> 8) * (1.0f / 16777216.0f);
71}
72
74 for (fl::size i = 0; i < mPx.size(); ++i)
75 mPx[i] = RGBf{};
76}
77
78float RingCanvas::posOf(int i) const {
79 const int n = size();
80 if (n <= 0)
81 return 0.0f;
82 return static_cast<float>(i) / static_cast<float>(n);
83}
84
85void RingCanvas::pixel(int i, const RGBf &color, float gain) {
86 const int n = size();
87 if (n <= 0 || gain <= 0.0f)
88 return;
89 i %= n;
90 if (i < 0)
91 i += n;
92 RGBf &p = mPx[static_cast<fl::size>(i)];
93 p.r += color.r * gain;
94 p.g += color.g * gain;
95 p.b += color.b * gain;
96}
97
98void RingCanvas::fill(const RGBf &color, float gain) {
99 const int n = size();
100 if (n <= 0 || gain <= 0.0f)
101 return;
102 for (int i = 0; i < n; ++i) {
103 RGBf &p = mPx[static_cast<fl::size>(i)];
104 p.r += color.r * gain;
105 p.g += color.g * gain;
106 p.b += color.b * gain;
107 }
108}
109
110void RingCanvas::lobe(float pos, float sigma, const RGBf &color, float gain) {
111 const int n = size();
112 if (n <= 0 || gain <= 0.0f || sigma <= 0.0f)
113 return;
114 for (int i = 0; i < n; ++i) {
115 const float k = falloff(ringDistance(posOf(i), pos), sigma);
116 if (k <= 0.0f)
117 continue;
118 pixel(i, color, gain * k);
119 }
120}
121
122void RingCanvas::ring(float origin, float radius, float sigma,
123 const RGBf &color, float gain) {
124 const int n = size();
125 if (n <= 0 || gain <= 0.0f || sigma <= 0.0f)
126 return;
127 for (int i = 0; i < n; ++i) {
128 float d = ringDistance(posOf(i), origin) - radius;
129 if (d < 0.0f)
130 d = -d;
131 const float k = falloff(d, sigma);
132 if (k <= 0.0f)
133 continue;
134 pixel(i, color, gain * k);
135 }
136}
137
138} // namespace mood_ring
int x
Definition simple.h:92
uint8_t pos
Definition Blur.ino:11
float posOf(int i) const
Position of pixel i in turns.
void pixel(int i, const RGBf &color, float gain)
Add to one pixel, index wrapped.
void lobe(float pos, float sigma, const RGBf &color, float gain)
Add a smooth lobe centred at pos (turns) with half-width sigma (turns).
void fill(const RGBf &color, float gain)
Add the same colour to every pixel.
fl::span< RGBf > mPx
Definition ring_canvas.h:92
void ring(float origin, float radius, float sigma, const RGBf &color, float gain)
Add a band at distance radius (turns, 0..0.5) from origin, on both sides of it at once: an expanding ...
float unit()
Uniform in [0, 1).
static uint32_t t
Definition Luminova.h:55
fl::CRGB CRGB
Definition crgb.h:25
unsigned char u8
Definition stdint.h:131
float smoothstepf(float e0, float e1, float x)
0 below e0, 1 above e1, smooth in between.
RGBf toRGBf(CRGB c)
float ringDistance(float a, float b)
Shortest distance between two ring positions, in turns, in [0, 0.5].
CRGB toCRGB(const RGBf &p)
float clampf(float v, float lo, float hi)
Definition ring_canvas.h:19
float ringOffset(float a, float b)
Signed shortest offset from b to a on the ring, in (-0.5, 0.5].
float falloff(float distance, float sigma)
Smooth bump: 1 at distance 0, 0 at distance >= sigma.
float wrapTurns(float t)
Wrap into [0, 1).
Linear-light float pixel, nominal range [0, 1], may exceed 1 before clip.
Definition ring_canvas.h:24