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