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/assert.h"
57#include "fl/corkscrew.h"
58#include "fl/grid.h"
59#include "fl/leds.h"
60#include "fl/screenmap.h"
61#include "fl/sstream.h"
62#include "fl/warn.h"
63#include "noise.h"
64#include <FastLED.h>
65// #include "vec3.h"
66
67using namespace fl;
68
69#define PIN_DATA 9
70
71#define NUM_LEDS 288
72#define CORKSCREW_TURNS 19 // Default to 19 turns
73
74// #define CM_BETWEEN_LEDS 1.0 // 1cm between LEDs
75// #define CM_LED_DIAMETER 0.5 // 0.5cm LED diameter
76
79 "Tests the ability to map a cork screw onto a 2D cylindrical surface");
80
81UISlider speed("Speed", 0.1f, 0.01f, 1.0f, 0.01f);
82
83UICheckbox allWhite("All White", false);
84UICheckbox splatRendering("Splat Rendering", true);
85UICheckbox cachingEnabled("Enable Tile Caching", true);
86
87// CRGB leds[NUM_LEDS];
88
89// Tested on a 288 led (2x 144 max density led strip) with 19 turns
90// Auto-calculates optimal grid dimensions from turns and LEDs
92 NUM_LEDS); // 288 leds
93
94// Create a corkscrew with:
95// - 30cm total length (300mm)
96// - 5cm width (50mm)
97// - 2mm LED inner diameter
98// - 24 LEDs per turn
99// fl::ScreenMap screenMap = makeCorkScrew(NUM_LEDS,
100// 300.0f, 50.0f, 2.0f, 24.0f);
101
102// fl::vector<vec3f> mapCorkScrew = makeCorkScrew(args);
105
106void setup() {
107 int width = corkscrew.cylinderWidth();
108 int height = corkscrew.cylinderHeight();
109
110 frameBuffer.reset(width, height);
111 XYMap xyMap = XYMap::constructRectangularGrid(width, height, 0);
112
113 CRGB *leds = frameBuffer.data();
114 size_t num_leds = frameBuffer.size();
115
117 &FastLED.addLeds<WS2812, 3, BGR>(leds, num_leds);
118
119 // NEW: Create ScreenMap directly from Corkscrew using toScreenMap()
120 // This maps each LED index to its exact position on the cylindrical surface
121 fl::ScreenMap corkscrewScreenMap = corkscrew.toScreenMap(0.2f);
122
123 // Alternative: Create ScreenMap from rectangular XYMap (old way)
124 // fl::ScreenMap screenMap = xyMap.toScreenMap();
125 // screenMap.setDiameter(.2f);
126
127 // Set the corkscrew screen map for the controller
128 // This allows the web interface to display the actual corkscrew shape
129 controller->setScreenMap(corkscrewScreenMap);
130
131 // Initialize caching based on UI setting
132 corkscrew.setCachingEnabled(cachingEnabled.value());
133}
134
135void loop() {
137 static float pos = 0;
138 pos += speed.value();
139 if (pos > corkscrew.size() - 1) {
140 pos = 0; // Reset to the beginning
141 }
142
143 // Update caching setting if it changed
144 static bool lastCachingState = cachingEnabled.value();
145 if (lastCachingState != cachingEnabled.value()) {
146 corkscrew.setCachingEnabled(cachingEnabled.value());
147 lastCachingState = cachingEnabled.value();
148 }
149
150 if (allWhite) {
151 for (size_t i = 0; i < frameBuffer.size(); ++i) {
152 frameBuffer.data()[i] = CRGB(8, 8, 8);
153 }
154 }
155
156 if (splatRendering) {
157 Tile2x2_u8_wrap pos_tile = corkscrew.at_wrap(pos);
158 const CRGB color = CRGB::Blue;
159 // Draw each pixel in the 2x2 tile using the new wrapping API
160 for (int dx = 0; dx < 2; ++dx) {
161 for (int dy = 0; dy < 2; ++dy) {
162 auto data = pos_tile.at(dx, dy);
163 vec2<u16> wrapped_pos = data.first; // Already wrapped position
164 uint8_t alpha = data.second; // Alpha value
165
166 if (alpha > 0) { // Only draw if there's some alpha
167 CRGB c = color;
168 c.nscale8(alpha); // Scale the color by the alpha value
169 frameBuffer.at(wrapped_pos.x, wrapped_pos.y) = c;
170 }
171 }
172 }
173 } else {
174 // None splat rendering, looks aweful.
175 vec2f pos_vec2f = corkscrew.at_no_wrap(pos);
176 vec2<u16> pos_i16 = vec2<u16>(round(pos_vec2f.x), round(pos_vec2f.y));
177 // Now map the cork screw position to the cylindrical buffer that we
178 // will draw.
179 frameBuffer.at(pos_i16.x, pos_i16.y) =
180 CRGB::Blue; // Draw a blue pixel at (w, h)
181 }
182 FastLED.show();
183}
CRGB leds[NUM_LEDS]
#define NUM_LEDS
uint8_t pos
Definition Blur.ino:11
fl::XYMap xyMap
Definition ColorBoost.h:61
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
Definition FastLED.cpp:74
central include file for FastLED, defines the CFastLED class/object
CLEDController * controller
uint16_t speed
Definition Noise.ino:63
Base definition for an LED controller.
WS2812 controller class.
Definition FastLED.h:218
Entry & at(u16 x, u16 y)
Definition tile2x2.cpp:65
static XYMap constructRectangularGrid(u16 width, u16 height, u16 offset=0)
Definition xymap.cpp:34
UICheckbox cachingEnabled("Enable Tile Caching", true)
fl::ScreenMap screenMap
Definition Corkscrew.h:103
UITitle festivalStickTitle("Corkscrew")
Corkscrew corkscrew(CORKSCREW_TURNS, NUM_LEDS)
void setup()
Definition Corkscrew.h:106
UICheckbox splatRendering("Splat Rendering", true)
fl::Grid< CRGB > frameBuffer
Definition Corkscrew.h:104
UICheckbox allWhite("All White", false)
#define CORKSCREW_TURNS
Definition Corkscrew.h:72
UIDescription festivalStickDescription("Tests the ability to map a cork screw onto a 2D cylindrical surface")
void loop()
Definition Corkscrew.h:135
void clear(CRGB(&arr)[N])
Definition clear.h:13
vec2< float > vec2f
Definition geometry.h:333
@ BGR
Blue, Green, Red (0210)
Definition eorder.h:19
IMPORTANT!
Definition crgb.h:20
Functions to generate and fill arrays with noise.
Corkscrew LED strip projection and rendering.
CRGB & nscale8(fl::u8 scaledown)
Scale down a RGB to N/256ths of its current brightness, using "plain math" dimming rules.
@ Blue
<div style='background:#0000FF;width:4em;height:4em;'></div>
Definition crgb.h:569
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:86
value_type y
Definition geometry.h:191
value_type x
Definition geometry.h:190
#define round(x)
Definition util.h:11