LED阵列的波环向外扩散显示效果
代码如下:
#include <FastLED.h>
#define MATRIX_WIDTH 16
#define MATRIX_HEIGHT16
#define NUM_LEDS (MATRIX_WIDTH * MATRIX_HEIGHT)
#define LED_PIN 16
#define BRIGHTNESS 80 // 更低亮度更柔和
#define MAX_WAVES 5 // 最大同时存在的波环数
CRGB leds;
// 波环结构体
struct Wave {
float radius; // 当前半径
float intensity; // 当前强度
bool active; // 是否激活
};
Wave waves;
// 效果参数
const float WAVE_SPEED = 0.4; // 波传播速度(更慢)
const float WAVE_WIDTH = 4.0; // 波环宽度(更宽)
const float DECAY_RATE = 0.96;// 衰减速率(更平缓)
const uint16_t WAVE_INTERVAL = 3000; // 新波生成间隔(ms)
const uint8_t BASE_HUE = 160; // 基础色调(淡蓝)
// 预计算数据
float distanceMap;
float maxRadius;
// 蛇形矩阵坐标转换
uint16_t XY(uint8_t x, uint8_t y) {
return (y % 2 == 0) ? (y * MATRIX_WIDTH) + x
: (y * MATRIX_WIDTH) + (MATRIX_WIDTH - 1 - x);
}
void setup() {
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
// 预计算距离矩阵
float centerX = (MATRIX_WIDTH-1)/2.0;
float centerY = (MATRIX_HEIGHT-1)/2.0;
for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
for(uint8_t x=0; x<MATRIX_WIDTH; x++){
float dx = x - centerX;
float dy = y - centerY;
distanceMap = sqrt(dx*dx + dy*dy);
}
}
maxRadius = distanceMap; // 最大半径(到角落的距离)
// 初始化波环
for(auto &w : waves) w.active = false;
}
void spawnWave() {
for(auto &w : waves){
if(!w.active){
w.radius = 0.0;
w.intensity = 1.0;
w.active = true;
return;
}
}
}
void loop() {
static uint32_t lastWaveTime = 0;
// 生成新波环
if(millis() - lastWaveTime > WAVE_INTERVAL){
spawnWave();
lastWaveTime = millis();
}
// 清空LED
memset8(leds, 0, NUM_LEDS * 3);
// 更新所有波环
for(auto &w : waves){
if(w.active){
// 更新波环参数
w.radius += WAVE_SPEED;
w.intensity *= DECAY_RATE;
// 波环失效条件
if(w.radius > maxRadius*1.2 || w.intensity < 0.05){
w.active = false;
continue;
}
// 绘制波环
for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
for(uint8_t x=0; x<MATRIX_WIDTH; x++){
float dist = distanceMap;
// 计算波环影响
float delta = abs(dist - w.radius);
float effect = exp(-pow(delta/WAVE_WIDTH, 2)) * w.intensity;
// 叠加颜色(加法混合)
float hue = BASE_HUE + w.radius*0.3; // 色相渐变
uint8_t val = constrain(effect * 255, 0, 255);
leds += CHSV(hue, 200, val);
}
}
}
}
// 添加中心常亮
leds = CHSV(BASE_HUE, 255, 50);
FastLED.show();
FastLED.delay(30); // 更流畅的动画
} 连续的波:
变量:
//===================== wave ====================================
#define MAX_WAVES 4 // 最大同时存在的波环数
struct Wave {
float radius;
float intensity;
bool active;
uint8_t generation;
bool hasTriggered;
};
Wave waves;
const float WAVE_SPEED = 0.4;
const float WAVE_WIDTH = 3.5;
const float DECAY_RATE = 0.96;
const float TRIGGER_DISTANCE = 2.5;
float distanceMap;
float maxRadius;
uint8_t center_x, center_y; // 修改变量名
void spawnWave(uint8_t gen);
//===============================================================
初始化:
//==================== wave ======================
// 修改中心坐标变量名
center_x = (MATRIX_WIDTH-1)/2;
center_y = (MATRIX_HEIGHT-1)/2;
for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
for(uint8_t x=0; x<MATRIX_WIDTH; x++){
float dx = x - center_x; // 修改变量名
float dy = y - center_y; // 修改变量名
distanceMap = sqrt(dx*dx + dy*dy);
}
}
maxRadius = distanceMap;
waves = {0.0, 1.0, true, 0, false};
for(uint8_t i=1; i<MAX_WAVES; i++) waves.active = false;
//================================================
实现:
//======================wave ======================
// 生成新波环(参数:代数)
void spawnWave(uint8_t gen) {
for(auto &w : waves){
if(!w.active){
w.radius = 0.0;
w.intensity = 1.0 - gen*0.15; // 每代强度递减
w.active = true;
w.generation = gen;
return;
}
}
}
void wave_vision() {
static uint32_t lastFrame = millis();
float deltaTime = (millis() - lastFrame)/1000.0;
lastFrame = millis();
fadeToBlackBy(leds, NUM_LEDS, 30);
for(uint8_t i=0; i<MAX_WAVES; i++){
if(waves.active){
Wave &w = waves;
w.radius += WAVE_SPEED * (1.0 + deltaTime);
w.intensity *= DECAY_RATE;
if(w.generation == 0 && !w.hasTriggered && w.radius >= TRIGGER_DISTANCE){
spawnWave(1);
w.hasTriggered = true;
}
if(w.radius > maxRadius || w.intensity < 0.1){
if(w.generation == 0){
w.radius = 0.0;
w.intensity = 1.0;
w.hasTriggered = false;
}else{
w.active = false;
}
}
for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
for(uint8_t x=0; x<MATRIX_WIDTH; x++){
float dist = distanceMap;
float delta = abs(dist - w.radius);
float effect = exp(-pow(delta/WAVE_WIDTH, 2)) * w.intensity;
// 修改中心区域判断条件变量名
if(x >= center_x-1 && x <= center_x &&
y >= center_y-1 && y <= center_y){ // 变量名修改
effect *= 0.2;
}
leds += CHSV(160 + w.generation*20, 200, effect * 200);
}
}
}
}
// 修改中心区域强制降亮部分变量名
for(uint8_t dx=0; dx<2; dx++){
for(uint8_t dy=0; dy<2; dy++){
uint16_t idx = XY(center_x-dx, center_y-dy); // 变量名修改
leds.nscale8(50);
}
}
FastLED.show();
FastLED.delay(30);
}
宽度调整、密度增加和随机性改进:
代码如下:
#include <FastLED.h>
#define MATRIX_WIDTH 16
#define MATRIX_HEIGHT16
#define NUM_LEDS (MATRIX_WIDTH * MATRIX_HEIGHT)
#define LED_PIN 16
#define BRIGHTNESS 90
#define MAX_WAVES 6// 增加最大波环数量
CRGB leds;
struct Wave {
float radius;
float intensity;
bool active;
uint8_t generation;
bool hasTriggered;
float speedVariation; // 速度随机因子
float widthVariation; // 宽度随机因子
float angleOffset; // 角度偏移(用于形状随机)
};
Wave waves;
// 调整后的参数
const float BASE_WAVE_SPEED = 0.45;// 基础速度
const float BASE_WAVE_WIDTH = 2.4f; // 基础宽度(减小)
const float DECAY_RATE = 0.955f;
const float TRIGGER_DISTANCE = 1.8f;// 缩短触发距离增加密度
float distanceMap;
float maxRadius;
uint8_t center_x, center_y;
uint16_t XY(uint8_t x, uint8_t y) {
return (y % 2 == 0) ? (y * MATRIX_WIDTH) + x
: (y * MATRIX_WIDTH) + (MATRIX_WIDTH - 1 - x);
}
// 带随机扰动的距离计算
float perturbedDistance(uint8_t x, uint8_t y, Wave &w) {
float dx = x - center_x;
float dy = y - center_y;
// 添加基于角度的随机扰动
float angle = atan2(dy, dx) + w.angleOffset;
float perturbation = 0.4f * sin(angle * 3 + w.radius * 0.5f);
return sqrt(dx*dx + dy*dy) * (1.0f + perturbation * 0.08f);
}
void setup() {
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
center_x = (MATRIX_WIDTH-1)/2;
center_y = (MATRIX_HEIGHT-1)/2;
// 预计算基础距离
for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
for(uint8_t x=0; x<MATRIX_WIDTH; x++){
float dx = x - center_x;
float dy = y - center_y;
distanceMap = sqrt(dx*dx + dy*dy);
}
}
maxRadius = distanceMap;
// 初始化第一个波环
waves = {
0.0f,
1.0f,
true,
0,
false,
random8(95, 105)/100.0f,// 初始速度随机
random8(95, 105)/100.0f,// 初始宽度随机
random8(0, 628)/100.0f // 初始角度偏移(0-2π)
};
for(uint8_t i=1; i<MAX_WAVES; i++) waves.active = false;
}
void spawnWave(uint8_t gen) {
for(uint8_t i=0; i<MAX_WAVES; i++){
if(!waves.active){
waves = {
0.0f,
1.0f - gen*0.12f,
true,
gen,
false,
random8(95, 105)/100.0f,// 速度随机因子
random8(90, 110)/100.0f,// 宽度随机因子
random8(0, 628)/100.0f // 新随机角度
};
return;
}
}
}
void loop() {
static uint32_t lastFrame = millis();
float deltaTime = (millis() - lastFrame)/1000.0f;
lastFrame = millis();
fadeToBlackBy(leds, NUM_LEDS, 25);// 加快淡出速度增加密度感
for(uint8_t i=0; i<MAX_WAVES; i++){
if(waves.active){
Wave &w = waves;
// 应用随机速度
w.radius += BASE_WAVE_SPEED * w.speedVariation * (1.0f + deltaTime);
w.intensity *= DECAY_RATE;
// 触发新波环
if(w.generation == 0 && !w.hasTriggered && w.radius >= TRIGGER_DISTANCE){
spawnWave(1);
w.hasTriggered = true;
}
// 波环生命周期管理
if(w.radius > maxRadius || w.intensity < 0.12f){
if(w.generation == 0){
// 重置核心波环并重新随机参数
w.radius = 0.0f;
w.intensity = 1.0f;
w.hasTriggered = false;
w.speedVariation = random8(95, 105)/100.0f;
w.widthVariation = random8(90, 110)/100.0f;
w.angleOffset = random8(0, 628)/100.0f;
}else{
w.active = false;
}
}
// 绘制波环
for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
for(uint8_t x=0; x<MATRIX_WIDTH; x++){
// 使用扰动后的距离计算
float dist = perturbedDistance(x, y, w);
float delta = abs(dist - w.radius);
// 应用随机宽度
float effectiveWidth = BASE_WAVE_WIDTH * w.widthVariation;
float effect = exp(-pow(delta/effectiveWidth, 2.2f)) * w.intensity;
// 中心抑制
if(x >= center_x-1 && x <= center_x && y >= center_y-1 && y <= center_y){
effect *= 0.15f;
}
// 颜色混合(添加轻微随机色相偏移)
uint8_t hue = 160 + w.generation*18 + w.radius*0.8f;
leds += CHSV(hue, 210, effect * 220);
}
}
}
}
// 强化中心暗区
for(uint8_t dx=0; dx<2; dx++){
for(uint8_t dy=0; dy<2; dy++){
uint16_t idx = XY(center_x-dx, center_y-dy);
leds.nscale8(40);// 更暗的中心
}
}
FastLED.show();
FastLED.delay(28);// 稍快的刷新率
}
页:
[1]