FastLED 3.9.15
Loading...
Searching...
No Matches
wave_simulation_real.h
Go to the documentation of this file.
1/*
2Wave simulation classes for 1D and 2D simulations. This is called _Real because
3there is a one to one mapping between the simulation and the LED grid. For
4flexible super sampling see wave_simluation.h.
5
6Based on works and code by Shawn Silverman.
7*/
8
9#pragma once
10
11#include <stdint.h>
12
13#include "fl/math_macros.h" // if needed for MAX/MIN macros
14#include "fl/namespace.h"
15#include "fl/scoped_ptr.h"
16#include "fl/vector.h"
17#include "fl/warn.h"
18
19#include "fl/ptr.h"
20#include "fl/supersample.h"
21#include "fl/xymap.h"
22#include "fx/fx.h"
23#include "fx/fx2d.h"
24
25namespace fl {
26
27namespace wave_detail {
28int16_t float_to_fixed(float f);
29
30// Convert fixed Q15 to float.
31float fixed_to_float(int16_t f);
32} // namespace wave_detail
33
35 public:
36 // Constructor:
37 // - length: inner simulation grid length (excluding the 2 boundary cells).
38 // - speed: simulation speed (in float, will be stored in Q15).
39 // - dampening: exponent so that the effective damping factor is
40 // 2^(dampening).
41 WaveSimulation1D_Real(uint32_t length, float speed = 0.16f,
42 int dampening = 6);
44
45 // Set simulation speed (courant parameter) using a float.
46 void setSpeed(float something);
47
48 // Set the dampening exponent (effective damping factor is 2^(dampening)).
49 void setDampening(int damp);
50
51 // Get the current dampening exponent.
52 int getDampenening() const;
53
54 // Get the simulation speed as a float.
55 float getSpeed() const;
56
57 void setHalfDuplex(bool on) { mHalfDuplex = on; }
58
59 bool getHalfDuplex() const { return mHalfDuplex; }
60
61
62 // Get the simulation value at the inner grid cell x (converted to float in
63 // the range [-1.0, 1.0]).
64 float getf(size_t x) const;
65
66 int16_t geti16(size_t x) const;
67 int16_t geti16Previous(size_t x) const;
68
69 int8_t geti8(size_t x) const { return static_cast<int8_t>(geti16(x) >> 8); }
70
71 // If mHalfDuplex is set then the the values are adjusted so that negative
72 // values will instead be represented by zero.
73 uint8_t getu8(size_t x) const {
74 int16_t value = geti16(x);
75 // Rebase the range from [-32768, 32767] to [0, 65535] then extract the
76 // upper 8 bits.
77 // return static_cast<uint8_t>(((static_cast<uint16_t>(value) + 32768))
78 // >>
79 // 8);
80 if (mHalfDuplex) {
81 uint16_t v2 = static_cast<uint16_t>(value);
82 v2 *= 2;
83 return static_cast<uint8_t>(v2 >> 8);
84 } else {
85 return static_cast<uint8_t>(
86 ((static_cast<uint16_t>(value) + 32768)) >> 8);
87 }
88 }
89
90 // Returns whether x is within the inner grid bounds.
91 bool has(size_t x) const;
92
93 // Set the value at grid cell x (expected range: [-1.0, 1.0]); the value is
94 // stored in Q15.
95 void set(size_t x, float value);
96
97 // Advance the simulation one time step.
98 void update();
99
100 private:
101 uint32_t length; // Length of the inner simulation grid.
102 // Two grids stored in fixed Q15 format, each with length+2 entries
103 // (including boundary cells).
106 size_t whichGrid; // Indicates the active grid (0 or 1).
107
108 int16_t mCourantSq; // Simulation speed (courant squared) stored in Q15.
109 int mDampenening; // Dampening exponent (damping factor = 2^(mDampenening)).
111 true; // Flag to restrict values to positive range during update.
112
113};
114
116 public:
117 // Constructor: Initializes the simulation with inner grid size (W x H).
118 // The grid dimensions include a 1-cell border on each side.
119 // Here, 'speed' is specified as a float (converted to fixed Q15)
120 // and 'dampening' is given as an exponent so that the damping factor is
121 // 2^dampening.
122 WaveSimulation2D_Real(uint32_t W, uint32_t H, float speed = 0.16f,
123 float dampening = 6.0f);
125
126 // Set the simulation speed (courantSq) using a float value.
127 void setSpeed(float something);
128
129 // Set the dampening factor exponent.
130 // The dampening factor used is 2^(dampening).
131 void setDampening(int damp);
132
133 // Get the current dampening exponent.
134 int getDampenening() const;
135
136 // Get the simulation speed as a float (converted from fixed Q15).
137 float getSpeed() const;
138
139 // Return the value at an inner grid cell (x,y), converted to float.
140 // The value returned is in the range [-1.0, 1.0].
141 float getf(size_t x, size_t y) const;
142
143 // Return the value at an inner grid cell (x,y) as a fixed Q15 integer
144 // in the range [-32768, 32767].
145 int16_t geti16(size_t x, size_t y) const;
146 int16_t geti16Previous(size_t x, size_t y) const;
147
148 int8_t geti8(size_t x, size_t y) const {
149 return static_cast<int8_t>(geti16(x, y) >> 8);
150 }
151
152 uint8_t getu8(size_t x, size_t y) const {
153 int16_t value = geti16(x, y);
154 // Rebase the range from [-32768, 32767] to [0, 65535] then extract the
155 // upper 8 bits.
156 // return static_cast<uint8_t>(((static_cast<uint16_t>(value) + 32768))
157 // >>
158 // 8);
159 if (mHalfDuplex) {
160 uint16_t v2 = static_cast<uint16_t>(value);
161 v2 *= 2;
162 return static_cast<uint8_t>(v2 >> 8);
163 } else {
164 return static_cast<uint8_t>(
165 ((static_cast<uint16_t>(value) + 32768)) >> 8);
166 }
167 }
168
169 void setXCylindrical(bool on) { mXCylindrical = on; }
170
171 // Check if (x,y) is within the inner grid.
172 bool has(size_t x, size_t y) const;
173
174 // Set the value at an inner grid cell using a float;
175 // the value is stored in fixed Q15 format.
176 // value shoudl be between -1.0 and 1.0.
177 void setf(size_t x, size_t y, float value);
178
179 void seti16(size_t x, size_t y, int16_t value);
180
181 void setHalfDuplex(bool on) { mHalfDuplex = on; }
182
183 bool getHalfDuplex() const { return mHalfDuplex; }
184
185 // Advance the simulation one time step using fixed-point arithmetic.
186 void update();
187
188 uint32_t getWidth() const { return width; }
189 uint32_t getHeight() const { return height; }
190
191 private:
192 uint32_t width; // Width of the inner grid.
193 uint32_t height; // Height of the inner grid.
194 uint32_t stride; // Row length (width + 2 for the borders).
195
196 // Two separate grids stored in fixed Q15 format.
199
200 size_t whichGrid; // Indicates the active grid (0 or 1).
201
202 int16_t mCourantSq; // Fixed speed parameter in Q15.
203 int mDampening; // Dampening exponent; used as 2^(dampening).
205 true; // Flag to restrict values to positive range during update.
206 bool mXCylindrical = false; // Default to non-cylindrical mode
207};
208
209} // namespace fl
uint32_t x[NUM_LAYERS]
Definition Fire2023.ino:82
uint32_t y[NUM_LAYERS]
Definition Fire2023.ino:83
UISlider dampening("Dampening", 6.0f, 0.0f, 10.0f, 0.1f)
void set(size_t x, float value)
int16_t geti16(size_t x) const
int16_t geti16Previous(size_t x) const
int8_t geti8(size_t x) const
uint8_t getu8(size_t x) const
WaveSimulation1D_Real(uint32_t length, float speed=0.16f, int dampening=6)
int16_t geti16Previous(size_t x, size_t y) const
int8_t geti8(size_t x, size_t y) const
bool has(size_t x, size_t y) const
fl::vector< int16_t, fl::allocator_psram< int16_t > > grid2
void setf(size_t x, size_t y, float value)
int16_t geti16(size_t x, size_t y) const
void seti16(size_t x, size_t y, int16_t value)
uint8_t getu8(size_t x, size_t y) const
WaveSimulation2D_Real(uint32_t W, uint32_t H, float speed=0.16f, float dampening=6.0f)
fl::vector< int16_t, fl::allocator_psram< int16_t > > grid1
float getf(size_t x, size_t y) const
uint16_t speed
Definition funky.cpp:82
Implements the FastLED namespace macros.
float fixed_to_float(int16_t f)
int16_t float_to_fixed(float f)
HeapVector< T, Allocator > vector
Definition vector.h:1074
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16