// 马尔科夫链增强平滑版本
struct MarkovState {
uint8_t baseHue; // 当前色相
uint8_t targetHue; // 目标色相(新增)
uint8_t speed;
uint8_t targetSpeed; // 新增目标速度
int8_t direction;
float directionF; // 新增浮点方向(用于平滑过渡)
uint8_t intensity;
};
MarkovState currentState = {200, 200, 3, 3, 1, 1.0f, 150};
const uint8_t transitionProb[4][4] = {
{90, 5, 3, 2}, // 提高保持色相的概率
{10, 85, 3, 2}, // 降低速度变化频率
{5, 5, 88, 2}, // 增强方向稳定性
{3, 2, 2, 93} // 提高强度保持率
};
uint32_t z = 0; // 改为32位防溢出
const float DIRECTION_TRANSITION = 0.1f; // 方向过渡系数
void applyMarkovTransition() {
static uint32_t lastChange = 0;
const uint32_t CHANGE_INTERVAL = 3000; // 延长状态变化间隔
if(millis() - lastChange < CHANGE_INTERVAL) return;
lastChange = millis();
uint8_t randVal = random8();
uint8_t probSum = 0;
uint8_t targetDim = 0;
// 概率累计方式优化
while(targetDim < 4 && randVal > (probSum += transitionProb[targetDim][targetDim])) {
targetDim++;
}
// 有限渐变状态转移
switch(targetDim) {
case 0: // 色相渐变
currentState.targetHue = constrain(currentState.baseHue + random8(-8, 9), 180, 255);
break;
case 1: // 速度渐变
currentState.targetSpeed = constrain(currentState.speed + random8(-1, 2), 1, 5);
break;
case 2: // 方向平滑过渡
currentState.directionF = -currentState.directionF; // 缓慢反转
break;
case 3: // 强度渐变
currentState.intensity = constrain(currentState.intensity + random8(-8, 9), 100, 200);
break;
}
}
void smoothUpdateStates() {
// 色相线性插值
currentState.baseHue = lerp8by8(currentState.baseHue, currentState.targetHue, 10);
// 速度指数平滑
currentState.speed = (currentState.speed * 7 + currentState.targetSpeed * 1) / 8;
// 方向浮点过渡
currentState.directionF += (currentState.direction - currentState.directionF) * DIRECTION_TRANSITION;
}
void generateWindPattern() {
const float dirFactor = currentState.directionF; // 使用浮点方向因子
for(uint8_t y=0; y<MATRIX_HEIGHT; y++) {
for(uint8_t x=0; x<MATRIX_WIDTH; x++) {
// 改进的噪声参数(增加Z轴细分)
uint8_t noise = inoise8(
(x * 25) + (z * dirFactor * 0.7f),
y * 35 + z * 0.3f,
currentState.intensity * 8 + (z >> 6)
);
// 循环色相映射(替代硬约束)
uint8_t hue = currentState.baseHue + map(noise, 0,255, -15,15);
hue = 180 + ((hue - 180) % 76); // 180-255循环
// 亮度S曲线处理
uint8_t val = cubicwave8(noise);
val = map(val, 30, 225, 50, 220); // 压缩两端
leds[XY(x,y)] = CHSV(hue, 235, val);
}
}
// 使用标准二维模糊 + 逐行模糊替代方案
blur2d(leds, MATRIX_WIDTH, MATRIX_HEIGHT, 64);
// 手动实现行模糊
for(uint8_t y=0; y<MATRIX_HEIGHT; y++) {
CRGB* rowStart = &leds[XY(0, y)];
blur1d(rowStart, MATRIX_WIDTH, 32);
}
z += currentState.speed;
}
void wind_vision() {
static uint32_t lastUpdate = 0;
if(millis() - lastUpdate > 33) { // 30FPS
lastUpdate = millis();
smoothUpdateStates(); // 先更新状态
applyMarkovTransition();
generateWindPattern();
// 添加残影效果
fadeToBlackBy(leds, NUM_LEDS, 220);
FastLED.show();
}
}