keer_zu 发表于 2025-5-23 12:19

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); // 更流畅的动画
}

keer_zu 发表于 2025-5-23 12:48

连续的波:

变量:

//===================== 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);
}


keer_zu 发表于 2025-5-23 13:02

宽度调整、密度增加和随机性改进:

代码如下:

#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]
查看完整版本: LED阵列的波环向外扩散显示效果