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