FastLED 3.9.15
Loading...
Searching...
No Matches
Corkscrew.h
Go to the documentation of this file.
1/*
2Basic cork screw test.
3
4This test is forward mapping, in which we test that
5the corkscrew is mapped to cylinder cartesian coordinates.
6
7Most of the time, you'll want the reverse mapping, that is
8drawing to a rectangular grid, and then mapping that to a corkscrew.
9
10However, to make sure the above mapping works correctly, we have
11to test that the forward mapping works correctly first.
12
13NEW: ScreenMap Support
14=====================
15You can now create a ScreenMap directly from a Corkscrew, which maps
16each LED index to its exact position on the cylindrical surface.
17This is useful for web interfaces and visualization:
18
19Example usage:
20```cpp
21// Create a corkscrew
22Corkscrew corkscrew(totalTurns, numLeds);
23
24// Create ScreenMap with 0.5cm LED diameter
25fl::ScreenMap screenMap = corkscrew.toScreenMap(0.5f);
26
27// Use with FastLED controller for web visualization
28controller->setScreenMap(screenMap);
29```
30
31NEW: Rectangular Buffer Support
32===============================
33You can now draw into a rectangular fl::Leds grid and read that
34into the corkscrew's internal buffer for display:
35
36Example usage:
37```cpp
38// Create a rectangular grid to draw into
39CRGB grid_buffer[width * height];
40fl::Leds grid(grid_buffer, width, height);
41
42// Draw your 2D patterns into the grid
43grid(x, y) = CRGB::Red; // etc.
44
45// Draw patterns on the corkscrew's surface and map to LEDs
46auto& surface = corkscrew.surface();
47// Draw your patterns on the surface, then call draw() to map to LEDs
48corkscrew.draw();
49
50// Access the LED pixel data
51auto ledData = corkscrew.data(); // Or corkscrew.rawData() for pointer
52// The LED data now contains the corkscrew mapping of your patterns
53```
54*/
55
56#include "fl/stl/assert.h"
57#include "fl/gfx/corkscrew.h"
58#include "fl/math/grid.h"
59#include "fl/gfx/leds.h"
60#include "fl/math/screenmap.h"
61#include "fl/stl/sstream.h"
62#include "fl/log/log.h"
63#include "noise.h"
64#include <FastLED.h>
65// #include "vec3.h"
66
67#define PIN_DATA 9
68
69#define NUM_LEDS 288
70#define CORKSCREW_TURNS 19 // Default to 19 turns
71
72// #define CM_BETWEEN_LEDS 1.0 // 1cm between LEDs
73// #define CM_LED_DIAMETER 0.5 // 0.5cm LED diameter
74
77 "Tests the ability to map a cork screw onto a 2D cylindrical surface");
78
79fl::UISlider speed("Speed", 0.1f, 0.01f, 1.0f, 0.01f);
80
81fl::UICheckbox allWhite("All White", false);
82fl::UICheckbox splatRendering("Splat Rendering", true);
83fl::UICheckbox cachingEnabled("Enable Tile Caching", true);
84
85// CRGB leds[NUM_LEDS];
86
87// Tested on a 288 led (2x 144 max density led strip) with 19 turns
88// Auto-calculates optimal grid dimensions from turns and LEDs
90 NUM_LEDS); // 288 leds
91
92// Create a corkscrew with:
93// - 30cm total length (300mm)
94// - 5cm width (50mm)
95// - 2mm LED inner diameter
96// - 24 LEDs per turn
97// fl::ScreenMap screenMap = makeCorkScrew(NUM_LEDS,
98// 300.0f, 50.0f, 2.0f, 24.0f);
99
100// fl::vector<vec3f> mapCorkScrew = makeCorkScrew(args);
103
104void setup() {
105 int width = corkscrew.cylinderWidth();
106 int height = corkscrew.cylinderHeight();
107
108 frameBuffer.reset(width, height);
110
112
114 &FastLED.addLeds<WS2812, 3, BGR>(leds.data(), leds.size());
115
116 // NEW: Create ScreenMap directly from Corkscrew using toScreenMap()
117 // This maps each LED index to its exact position on the cylindrical surface
118 fl::ScreenMap corkscrewScreenMap = corkscrew.toScreenMap(0.2f);
119
120 // Alternative: Create ScreenMap from rectangular XYMap (old way)
121 // fl::ScreenMap screenMap = xyMap.toScreenMap();
122 // screenMap.setDiameter(.2f);
123
124 // Set the corkscrew screen map for the controller
125 // This allows the web interface to display the actual corkscrew shape
126 controller->setScreenMap(corkscrewScreenMap);
127
128 // Initialize caching based on UI setting
129 corkscrew.setCachingEnabled(cachingEnabled.value());
130}
131
132void loop() {
134 static float pos = 0; // okay static in header
135 pos += speed.value();
136 if (pos > corkscrew.size() - 1) {
137 pos = 0; // Reset to the beginning
138 }
139
140 // Update caching setting if it changed
141 static bool lastCachingState = cachingEnabled.value(); // okay static in header
142 if (lastCachingState != cachingEnabled.value()) {
143 corkscrew.setCachingEnabled(cachingEnabled.value());
144 lastCachingState = cachingEnabled.value();
145 }
146
147 if (allWhite) {
148 for (size_t i = 0; i < frameBuffer.size(); ++i) {
149 frameBuffer.span()[i] = CRGB(8, 8, 8);
150 }
151 }
152
153 if (splatRendering) {
154 fl::Tile2x2_u8_wrap pos_tile = corkscrew.at_wrap(pos);
155 const fl::CRGB color = fl::CRGB::Blue;
156 // Draw each pixel in the 2x2 tile using the new wrapping API
157 for (int dx = 0; dx < 2; ++dx) {
158 for (int dy = 0; dy < 2; ++dy) {
159 auto data = pos_tile.at(dx, dy);
160 fl::vec2<fl::u16> wrapped_pos = data.first; // Already wrapped position
161 uint8_t alpha = data.second; // Alpha value
162
163 if (alpha > 0) { // Only draw if there's some alpha
164 fl::CRGB c = color;
165 c.nscale8(alpha); // Scale the color by the alpha value
166 frameBuffer.at(wrapped_pos.x, wrapped_pos.y) = c;
167 }
168 }
169 }
170 } else {
171 // None splat rendering, looks aweful.
172 fl::vec2f pos_vec2f = corkscrew.at_no_wrap(pos);
173 fl::vec2<fl::u16> pos_i16 = fl::vec2<fl::u16>(round(pos_vec2f.x), round(pos_vec2f.y));
174 // Now map the cork screw position to the cylindrical buffer that we
175 // will draw.
176 frameBuffer.at(pos_i16.x, pos_i16.y) =
177 fl::CRGB::Blue; // Draw a blue pixel at (w, h)
178 }
179 FastLED.show();
180}
fl::XYMap xyMap
#define NUM_LEDS
fl::CRGB leds[NUM_LEDS]
uint8_t pos
Definition Blur.ino:11
fl::UICheckbox allWhite("All White", false)
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
CLEDController * controller
uint16_t speed
Definition Noise.ino:66
Entry & at(u16 x, u16 y)
static XYMap constructRectangularGrid(u16 width, u16 height, u16 offset=0) FL_NOEXCEPT
Definition xymap.cpp.hpp:35
fl::CLEDController CLEDController
constexpr EOrder BGR
Definition eorder.h:22
fl::ScreenMap screenMap
Definition Corkscrew.h:101
fl::UICheckbox splatRendering("Splat Rendering", true)
fl::UITitle festivalStickTitle("Corkscrew")
void setup()
Definition Corkscrew.h:104
fl::Corkscrew corkscrew(CORKSCREW_TURNS, NUM_LEDS)
fl::Grid< CRGB > frameBuffer
Definition Corkscrew.h:102
#define CORKSCREW_TURNS
Definition Corkscrew.h:70
fl::UICheckbox cachingEnabled("Enable Tile Caching", true)
fl::UIDescription festivalStickDescription("Tests the ability to map a cork screw onto a 2D cylindrical surface")
void loop()
Definition Corkscrew.h:132
fl::CRGB CRGB
Definition crgb.h:25
Centralized logging categories for FastLED hardware interfaces and subsystems.
void clear(CRGB(&arr)[N])
Definition clear.h:12
vec2< float > vec2f
Definition geometry.h:333
Corkscrew LED strip projection and rendering.
CRGB & nscale8(u8 scaledown) FL_NOEXCEPT
Scale down a RGB to N/256ths of its current brightness, using "plain math" dimming rules.
Definition crgb.cpp.hpp:88
@ Blue
<div style='background:#0000FF;width:4em;height:4em;'></div>
Definition crgb.h:512
Representation of an 8-bit RGB pixel (Red, Green, Blue)
Definition crgb.h:38
value_type y
Definition geometry.h:191
value_type x
Definition geometry.h:190
#define round(x)
Definition util.h:11