news 2026/9/29 22:18:13

weathr雨滴模拟全解:从风向量分解到地面溅落,快速看懂终端天气动画的终端物理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
weathr雨滴模拟全解:从风向量分解到地面溅落,快速看懂终端天气动画的终端物理

weathr雨滴模拟全解:从风向量分解到地面溅落,快速看懂终端天气动画的终端物理

【免费下载链接】weathra terminal weather app with ascii animation项目地址: https://gitcode.com/gh_mirrors/wea/weathr

weathr 是一款开源的终端天气应用(terminal weather app with ASCII animation),用实时天气数据驱动 ASCII 动画。本文带你从源码层面拆解它最有物理感的部分——raindrops.rs 里的雨滴模拟:风向角如何分解成雨幕的斜度、四层雨量等级如何决定雨滴密度与字符、以及地面溅落动画的 3 帧时序。全程以参数和图表演示为主,零基础也能看懂。

🌧️ 雨幕从哪里来:RainIntensity 的 4 个等级

雨滴系统不直接读降水量,而是先经过一次"翻译":types.rs 中的rain_intensity()把天气类型映射为 4 个等级——毛毛雨、小雨、大雨、暴雨。

等级触发天气雨滴数量(相对终端宽度)基础风速 wind_x下落速度
毛毛雨 DrizzleDrizzle宽度 ÷ 40.050.2 ~ 0.4
小雨 LightRain、RainShowers宽度 ÷ 20.10.4 ~ 0.7
大雨 HeavyFreezingRain、Thunderstorm宽度 × 10.150.6 ~ 0.9
暴雨 StormThunderstormHail宽度 × 1.50.81.2 ~ 1.8

数量公式与速度参数分别定义在 raindrops.rs 和 raindrops.rs。注意一个细节:雨滴不是一下子铺满屏幕的,而是每帧按 1/2/5 的"生成速率"逐渐补满目标数量,所以开场会有雨幕渐浓的过渡感。

🌬️ 风向角分解:把 225° 变成雨幕斜度

这是全篇最"物理"的一步。气象学里的风向是风来的方位角(0°=北,90°=东),而屏幕只需要一个横向漂移速度。set_wind 的分解公式是:

wind_x = (风速 ÷ 40) × sin(−风向角)

为什么这样对?拿三个数字验证一下:

  • 北风 0°:sin(0) = 0 → 雨垂直下坠,左右没有漂移,符合"正对吹来的风不改变水平位移"的直觉;
  • 东风 90°:sin(−90°) = −1 → 雨被往左吹,正对着从东边来的风;
  • 西南风 225°(模拟模式默认值,见 app.rs):sin(−225°) ≈ 0.71 → 向右飘。

风速除以一个 40 的"归一化常数",意味着40 km/h 就是满偏:再大的风也只是逼近极限斜度,雨幕不会失控飞离屏幕。

而渲染阶段的判据同样精巧:横向速度 |speed_x| 超过 0.5 时,字符强制切换为\(向右)或/(向左)(raindrops.rs)。所以"雨滴斜度"其实是被速度阈值驱动的状态机,而不是直接画直线——大风吹过时你会看到整片雨幕"齐刷刷"斜过去。

🪟 双层深度:z_index 制造的前景/背景雨

spawn_drop 里给每颗雨滴随机分配 z_index 0 或 1,相当于远近两层:

层级速度颜色角色
远景 z=0较慢DarkGrey背景薄雨
近景 z=1较快青色/白色前景清晰雨丝

而且只有近景雨滴才允许触发地面溅落。远景那层是灰色的"慢速雨",近景是亮的"快速雨"——两层叠加就产生了终端里难得的纵深错觉。另外每颗雨滴还会叠加一点随机扰动(纵向 ±20%、横向 ±10%),让雨丝彼此错开,避免"整齐划一"的机械感。

💦 地面溅落:3 帧 1 秒的白色涟漪

雨滴的下落循环在 update:每帧 y 加纵向速度、x 加横向速度;一旦到达地面行(终端高度 −1),先按等级概率(10% / 30% / 60%)掷骰子决定是否生成 Splash,然后雨滴本体销毁。

Splash 本体只是一个(x, y, timer, max_timer)结构,生命只有 3 帧,渲染时在原地依次打出:

帧0: '.' → 帧1: 'o' → 帧2: 'O' → 帧3: ' '(消散)

一个字符从小圆点滚到大圆圈,就是那圈水花(render)。为防止大雨天溅落刷屏,MAX_SPLASHES = 100 做了硬上限,超出就从队首丢弃最老的溅落。最终这些字符由 TerminalRenderer 的双缓冲机制合帧输出——只把变化的格子写入终端,所以满屏雨滴也依然流畅。

⚙️ 事件驱动:风与雨量如何实时灌进雨幕

雨滴系统并不是死循环里硬编码参数,而是挂在动画框架的事件总线上(system.rs 定义的AnimationSystemtrait):

  • 天气数据到达 → AnimationManager 广播on_rain_intensity与on_wind→ 雨滴系统更新等级与 wind_x;
  • 终端窗口缩放 →on_resize自动清理越界的雨滴与溅落;
  • 是否激活 → 由 is_active 判断当前条件是否在降雨或雷暴。

这就是为什么你在 HUD 上看到风速从 10 km/h 跳到 45 km/h 时,雨幕会立刻整体斜过来——参数是流式更新的。

🖥️ 动手体验:3 条命令看完全部效果

# 模拟普通降雨 weathr --simulate rain # 模拟雷暴(Storm 级 + 45 km/h 大风,雨丝明显斜飞) weathr --simulate thunderstorm # 对比场景:降雪 / 晴朗 weathr --simulate snow weathr --simulate clear

运行后按q即可退出。下面的夜景与降雪演示和雷暴雨幕放在一起,能直观感受到同一套框架下不同粒子系统(雨 / 雪 / 星月)的差异:

📌 小结

weathr 的雨滴模拟用不到 300 行代码串起了三个物理概念:向量分解(风向角 → 横向漂移)、状态阈值(速度超 0.5 才斜雨)、有限寿命粒子(3 帧溅落)。如果你也想给终端项目加一点"物理感",这套"归一化风速 + 阈值字符切换 + 寿命计时器"的组合拳非常值得参考。

【免费下载链接】weathra terminal weather app with ascii animation项目地址: https://gitcode.com/gh_mirrors/wea/weathr

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 22:17:15

179、MLIR的Profiling(性能分析)与Timing(计时)Pass

MLIR的Profiling(性能分析)与Timing(计时)Pass 上周帮团队调一个AI推理引擎的算子性能问题,模型跑在自研NPU上,某个卷积算子的延迟比预期高了3倍。常规手段——插桩、打印时间戳、甚至用perf去抓——都试了,结果发现瓶颈不在计算本身,而在MLIR编译后的IR调度上。那个调…

作者头像 李华
网站建设 2026/9/29 22:15:18

广东芯片封装选型实录:空洞率从18%压到4.6%

上个月去东莞拜访一位做电动工具控制器多年的老熟人,他的团队去年走完了一个芯片封装项目,从工程批到客户认证一次通过。这顿下午茶喝得不亏,我把整个项目从头到尾替他复盘了一遍,细节做了脱敏,数据都是实打实的。 项目…

作者头像 李华
网站建设 2026/9/29 22:13:55

新手AI的入门必知

1. 引言 随着 AI 生态的共建,AI 早已从问答知识库发展成了“全能助理”。无论是创意发展、内容生成,还是日常办公、代码编写,AI 都在扮演越来越重要的角色。然而,AI 入门看似简单,实则学问不少——从模型选择、提示词设…

作者头像 李华
网站建设 2026/9/29 22:13:30

武汉奥迪动力受限顿挫挂挡异常?从发动机到变速箱这样查

武汉奥迪车主碰到加不起油门、起步顿挫、挂不上挡,最常听到一句话:"变速箱坏了,得大修。"这话多数时候下早了。毛病可能在发动机,可能在变速箱,也可能只是一段线束接触不良、一个程序版本没更新——不检查就…

作者头像 李华
网站建设 2026/9/29 22:13:26

2026企业AI办公工具选型全指南:能力评估框架与行业全景盘点

不少企业在调研AI办公工具的初期,很容易陷入几个典型的选型误区:把不同产品的功能列表拉出来逐项比对,谁覆盖的功能点多就优先纳入候选池;单纯对比不同产品的订阅成本,把价格作为决策的核心权重;或是直接参…

作者头像 李华