宽度调整、密度增加和随机性改进:
代码如下:
- #include <FastLED.h>
- #define MATRIX_WIDTH 16
- #define MATRIX_HEIGHT 16
- #define NUM_LEDS (MATRIX_WIDTH * MATRIX_HEIGHT)
- #define LED_PIN 16
- #define BRIGHTNESS 90
- #define MAX_WAVES 6 // 增加最大波环数量
- CRGB leds[NUM_LEDS];
- struct Wave {
- float radius;
- float intensity;
- bool active;
- uint8_t generation;
- bool hasTriggered;
- float speedVariation; // 速度随机因子
- float widthVariation; // 宽度随机因子
- float angleOffset; // 角度偏移(用于形状随机)
- };
- Wave waves[MAX_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[MATRIX_WIDTH][MATRIX_HEIGHT];
- 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[x][y] = sqrt(dx*dx + dy*dy);
- }
- }
- maxRadius = distanceMap[0][0];
- // 初始化第一个波环
- waves[0] = {
- 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[i].active = false;
- }
- void spawnWave(uint8_t gen) {
- for(uint8_t i=0; i<MAX_WAVES; i++){
- if(!waves[i].active){
- waves[i] = {
- 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[i].active){
- Wave &w = waves[i];
-
- // 应用随机速度
- 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[XY(x,y)] += 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[idx].nscale8(40); // 更暗的中心
- }
- }
- FastLED.show();
- FastLED.delay(28); // 稍快的刷新率
- }
|