FastLED 3.9.15
Loading...
Searching...
No Matches
xypath.cpp
Go to the documentation of this file.
1
2
3#ifdef __AVR__
4
5// do nothing
6
7#else
8
9#include <math.h>
10
11#include "fl/assert.h"
12#include "fl/function.h"
13#include "fl/gradient.h"
14#include "fl/lut.h"
15#include "fl/map_range.h"
16#include "fl/math_macros.h"
17#include "fl/raster.h"
18#include "fl/xypath.h"
19#include "fl/xypath_renderer.h"
20
21#include "fl/thread_local.h"
22
23namespace fl {
24
25namespace { // anonymous namespace
26
28 static ThreadLocal<XYRasterU8Sparse> tls_raster;
29 return tls_raster.access();
30}
31
32} // namespace
33
34namespace xypath_detail {
35fl::Str unique_missing_name(const char *prefix) {
36 static int sUniqueName = 0;
37 int id = ++sUniqueName;
38 Str name = prefix;
39 name += id;
40 return name;
41}
42} // namespace xypath_detail
43
44vec2f XYPath::at(float alpha, const TransformFloat &tx) {
45 // return compute_float(alpha, tx);
46 return mPathRenderer->at(alpha, tx);
47}
48
49void XYPath::setDrawBounds(uint16_t width, uint16_t height) {
50 mPathRenderer->setDrawBounds(width, height);
51}
52
53void XYPath::setScale(float scale) { mPathRenderer->setScale(scale); }
54
55Str XYPath::name() const { return mPath->name(); }
57 return mPathRenderer->at_subpixel(alpha);
58}
59
60void XYPath::rasterize(float from, float to, int steps,
62 XYPath::AlphaFunction *optional_alpha_gen) {
63 mPathRenderer->rasterize(from, to, steps, raster, optional_alpha_gen);
64}
65
66vec2f XYPath::at(float alpha) { return mPathRenderer->at(alpha); }
67
69
70XYPath::XYPath(XYPathGeneratorPtr path, TransformFloat transform)
71 : mPath(path) {
72 mPathRenderer = XYPathRendererPtr::New(path, transform);
73}
74
76
78 float from, float to, int steps, XYRaster &raster,
79 fl::function<uint8_t(float)> *optional_alpha_gen) {
80 for (int i = 0; i < steps; ++i) {
81 float alpha = fl::map_range<int, float>(i, 0, steps - 1, from, to);
82 Tile2x2_u8 tile = at_subpixel(alpha);
83 if (optional_alpha_gen) {
84 // Scale the tile based on the alpha value.
85 uint8_t a8 = (*optional_alpha_gen)(alpha);
86 tile.scale(a8);
87 }
88 raster.rasterize(tile);
89 }
90}
91
92void XYPathRenderer::setDrawBounds(uint16_t width, uint16_t height) {
93 // auto &tx = *(mGridTransform.mImpl);
94 auto &tx = mGridTransform;
95
96 // 1) map world‑X ∈ [–1..+1] → pixel‑X ∈ [0.5 .. width–0.5]
97 // scale_x = ( (width–0.5) – 0.5 ) / 2 = (width–1)/2
98 // offset_x = (width–0.5 + 0.5) / 2 = width/2
99 tx.set_scale_x((width - 1.0f) * 0.5f);
100 // tx.scale_x = (width - 1.0f) * 0.5f;
101 // tx.offset_x = width * 0.5f;
102 tx.set_offset_x(width * 0.5f);
103
104 // 2) map world‑Y ∈ [ -1 .. 1 ] → pixel‑Y ∈ [0.5 .. height–0.5]
105 // (your LinePath lives at Y=0, so it will sit at row‑0 center = 0.5)
106 // scale_y = (height–0.5) – 0.5 = height–1
107 // offset_y = 0.5
108 // tx.scale_y = (height - 1.0f) * 0.5f;
109 // tx.offset_y = height * 0.5f;
110
111 tx.set_scale_y((height - 1.0f) * 0.5f);
112 tx.set_offset_y(height * 0.5f);
113
115 mDrawBoundsSet = true;
116}
117
119 // Future use to allow recomputing the LUT.
120}
121
123
125 // mTransform.scale_x = scale;
126 // mTransform.scale_y = scale;
127 mTransform.set_scale(scale);
129}
130
132 return compute_float(alpha, mTransform);
133}
134
135vec2f XYPathRenderer::at(float alpha) { return at(alpha, mTransform); }
136
137vec2f XYPathRenderer::at(float alpha, const TransformFloat &tx) {
138 return compute_float(alpha, tx);
139}
140
141XYPathPtr XYPath::NewPointPath(float x, float y) {
142 auto path = PointPathPtr::New(x, y);
143 return XYPathPtr::New(path);
144}
145
146XYPathPtr XYPath::NewLinePath(float x0, float y0, float x1, float y1) {
147 LinePathParamsPtr p = LinePathParamsPtr::New();
148 auto &params = *p;
149 params.x0 = x0;
150 params.y0 = y0;
151 params.x1 = x1;
152 params.y1 = y1;
153 auto path = LinePathPtr::New(p);
154 return XYPathPtr::New(path);
155}
156
157XYPathPtr XYPath::NewLinePath(const Ptr<LinePathParams> &params) {
158 auto path = NewPtr<LinePath>(params);
159 return XYPathPtr::New(path);
160}
161
163 auto path = CirclePathPtr::New();
164 return XYPathPtr::New(path);
165}
166
167XYPathPtr XYPath::NewCirclePath(uint16_t width, uint16_t height) {
168 CirclePathPtr path = CirclePathPtr::New();
169 XYPathPtr out = XYPathPtr::New(path);
170 out->setDrawBounds(width, height);
171 return out;
172}
173
175 HeartPathPtr path = HeartPathPtr::New();
176 return XYPathPtr::New(path);
177}
178
179XYPathPtr XYPath::NewHeartPath(uint16_t width, uint16_t height) {
180 HeartPathPtr path = HeartPathPtr::New();
181 XYPathPtr out = XYPathPtr::New(path);
182 out->setDrawBounds(width, height);
183 return out;
184}
185
186XYPathPtr XYPath::NewArchimedeanSpiralPath(uint16_t width, uint16_t height) {
187 ArchimedeanSpiralPathPtr path = ArchimedeanSpiralPathPtr::New();
188 XYPathPtr out = XYPathPtr::New(path);
189 out->setDrawBounds(width, height);
190 return out;
191}
192
194 ArchimedeanSpiralPathPtr path = ArchimedeanSpiralPathPtr::New();
195 XYPathPtr out = XYPathPtr::New(path);
196 return out;
197}
198
199XYPathPtr XYPath::NewRosePath(uint16_t width, uint16_t height,
200 const Ptr<RosePathParams> &params) {
201 RosePathPtr path = RosePathPtr::New(params);
202 XYPathPtr out = XYPathPtr::New(path);
203 if (width > 0 && height > 0) {
204 out->setDrawBounds(width, height);
205 }
206 return out;
207}
208
209XYPathPtr XYPath::NewPhyllotaxisPath(uint16_t width, uint16_t height,
211 PhyllotaxisPathPtr path = PhyllotaxisPathPtr::New(args);
212 XYPathPtr out = XYPathPtr::New(path);
213 if (width > 0 && height > 0) {
214 out->setDrawBounds(width, height);
215 }
216 return out;
217}
218
219XYPathPtr XYPath::NewGielisCurvePath(uint16_t width, uint16_t height,
220 const Ptr<GielisCurveParams> &params) {
221 GielisCurvePathPtr path = GielisCurvePathPtr::New(params);
222 XYPathPtr out = XYPathPtr::New(path);
223 if (width > 0 && height > 0) {
224 out->setDrawBounds(width, height);
225 }
226 return out;
227}
228
229XYPathPtr XYPath::NewCatmullRomPath(uint16_t width, uint16_t height,
230 const Ptr<CatmullRomParams> &params) {
231 CatmullRomPathPtr path = CatmullRomPathPtr::New(params);
232 XYPathPtr out = XYPathPtr::New(path);
233 if (width > 0 && height > 0) {
234 out->setDrawBounds(width, height);
235 }
236 return out;
237}
238
239XYPathPtr XYPath::NewCustomPath(const fl::function<vec2f(float)> &f,
240 const rect<int> &drawbounds,
242 const char *name) {
243
244 XYPathFunctionPtr path = NewPtr<XYPathFunction>(f);
245 path->setName(name);
246 if (!drawbounds.empty()) {
247 path->setDrawBounds(drawbounds);
248 }
249 XYPathPtr out = XYPathPtr::New(path);
250 if (!transform.is_identity()) {
251 out->setTransform(transform);
252 }
253 rect<int> bounds;
254 if (path->hasDrawBounds(&bounds)) {
255 if (!bounds.mMin.is_zero()) {
256 // Set the bounds to the path's bounds
258 "Bounds with an origin other than 0,0 is not supported yet");
259 }
260 auto w = bounds.width();
261 auto h = bounds.height();
262 out->setDrawBounds(w, h);
263 }
264 return out;
265}
266
270
271void XYPath::drawColor(const CRGB &color, float from, float to, Leds *leds,
272 int steps) {
273 XYRasterU8Sparse &raster = get_tls_raster();
274 raster.clear();
275 steps = steps > 0 ? steps : calculateSteps(from, to);
276 rasterize(from, to, steps, raster);
277 raster.draw(color, leds->xymap(), leds->rgb());
278}
279
280void XYPath::drawGradient(const Gradient &gradient, float from, float to,
281 Leds *leds, int steps) {
282 XYRasterU8Sparse &raster = get_tls_raster();
283 raster.clear();
284 steps = steps > 0 ? steps : calculateSteps(from, to);
285 rasterize(from, to, steps, raster);
286 raster.drawGradient(gradient, leds->xymap(), leds->rgb());
287}
288
289int XYPath::calculateSteps(float from, float to) {
290 float diff = fl::clamp(ABS(to - from), 0.0f, 1.0f);
291 return MAX(1, 200 * diff);
292}
293
294bool XYPath::hasDrawBounds() const { return mPathRenderer->hasDrawBounds(); }
295
296} // namespace fl
297
298#endif // __AVR__
CRGB leds[NUM_LEDS]
Definition Apa102.ino:11
int y
Definition Audio.ino:72
int x
Definition Audio.ino:71
UISlider scale("Scale", 1.0f, 0.0f, 1.0f, 0.01f)
XYRaster raster(WIDTH, HEIGHT)
friend class Ptr
Definition ptr.h:421
Definition str.h:389
void scale(uint8_t scale)
Definition tile2x2.cpp:24
fl::function< uint8_t(float)> AlphaFunction
Definition xypath.h:86
XYPathGeneratorPtr mPath
Definition xypath.h:134
static XYPathPtr NewGielisCurvePath(uint16_t width=0, uint16_t height=0, const Ptr< GielisCurveParams > &params=NewPtr< GielisCurveParams >())
Definition xypath.cpp:219
Str name() const
Definition xypath.cpp:55
int calculateSteps(float from, float to)
Definition xypath.cpp:289
void drawColor(const CRGB &color, float from, float to, Leds *leds, int steps=-1)
Definition xypath.cpp:271
static XYPathPtr NewHeartPath()
Definition xypath.cpp:174
static XYPathPtr NewArchimedeanSpiralPath()
Definition xypath.cpp:193
Tile2x2_u8 at_subpixel(float alpha)
Definition xypath.cpp:56
static XYPathPtr NewCustomPath(const fl::function< vec2f(float)> &path, const rect< int > &drawbounds=rect< int >(), const TransformFloat &transform=TransformFloat(), const char *name=nullptr)
Definition xypath.cpp:239
virtual ~XYPath()
Definition xypath.cpp:75
void setScale(float scale)
Definition xypath.cpp:53
vec2f at(float alpha)
Definition xypath.cpp:66
static XYPathPtr NewCatmullRomPath(uint16_t width=0, uint16_t height=0, const Ptr< CatmullRomParams > &params=NewPtr< CatmullRomParams >())
Definition xypath.cpp:229
static XYPathPtr NewPointPath(float x, float y)
Definition xypath.cpp:141
bool hasDrawBounds() const
Definition xypath.cpp:294
void setDrawBounds(uint16_t width, uint16_t height)
Definition xypath.cpp:49
void drawGradient(const Gradient &gradient, float from, float to, Leds *leds, int steps=-1)
Definition xypath.cpp:280
void setTransform(const TransformFloat &transform)
Definition xypath.cpp:267
static XYPathPtr NewLinePath(float x0, float y0, float x1, float y1)
Definition xypath.cpp:146
XYPathRendererPtr mPathRenderer
Definition xypath.h:135
static XYPathPtr NewPhyllotaxisPath(uint16_t width=0, uint16_t height=0, const Ptr< PhyllotaxisParams > &args=NewPtr< PhyllotaxisParams >())
Definition xypath.cpp:209
XYPath(XYPathGeneratorPtr path, TransformFloat transform=TransformFloat())
Definition xypath.cpp:70
static XYPathPtr NewRosePath(uint16_t width=0, uint16_t height=0, const Ptr< RosePathParams > &params=NewPtr< RosePathParams >())
Definition xypath.cpp:199
void rasterize(float from, float to, int steps, XYRasterU8Sparse &raster, AlphaFunction *optional_alpha_gen=nullptr)
Definition xypath.cpp:60
static XYPathPtr NewCirclePath()
Definition xypath.cpp:162
TransformFloat & transform()
Definition xypath.cpp:68
TransformFloat & transform()
Definition xypath.cpp:122
void rasterize(float from, float to, int steps, XYRasterU8Sparse &raster, fl::function< uint8_t(float)> *optional_alpha_gen=nullptr)
Definition xypath.cpp:77
vec2f compute(float alpha)
Definition xypath.cpp:131
Tile2x2_u8 at_subpixel(float alpha)
TransformFloat mTransform
TransformFloat mGridTransform
vec2f compute_float(float alpha, const TransformFloat &tx)
void setDrawBounds(uint16_t width, uint16_t height)
Definition xypath.cpp:92
void onTransformFloatChanged()
Definition xypath.cpp:118
void setScale(float scale)
Definition xypath.cpp:124
vec2f at(float alpha)
Definition xypath.cpp:135
UISlider steps("Steps", 100.0f, 1.0f, 200.0f, 1.0f)
#define ABS(x)
Definition math_macros.h:19
#define MAX(a, b)
Definition math_macros.h:11
XYRasterU8Sparse & get_tls_raster()
Definition xypath.cpp:27
fl::Str unique_missing_name(const char *prefix)
Definition xypath.cpp:35
XYRasterU8Sparse XYRaster
Definition raster.h:8
FASTLED_FORCE_INLINE T clamp(T value, T min, T max)
Definition clamp.h:10
ThreadLocalFake< T > ThreadLocal
vec2< float > vec2f
Definition geometry.h:318
Ptr< T > NewPtr(Args... args)
Definition ptr.h:451
FASTLED_FORCE_INLINE U map_range(T value, T in_min, T in_max, U out_min, U out_max)
Definition map_range.h:26
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16
static FASTLED_NAMESPACE_BEGIN uint8_t const p[]
Definition noise.cpp:30
corkscrew_args args
Definition old.h:142
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:55
uint16_t width() const
Definition geometry.h:408
uint16_t height() const
Definition geometry.h:410
bool empty() const
Definition geometry.h:412
vec2< T > mMin
Definition geometry.h:399
#define FASTLED_WARN
Definition warn.h:7