跳转至

气动模型:现实 vs 游戏

风帆(Create 普通帆)与对称风帆(Simulated Symmetric Sail)在游戏里如何产生升力与阻力,以及为什么不能照搬现实航空学。公式与系数来自 Sable / Simulated 源码(BlockSubLevelLiftProvider.sable$contributeLiftAndDrag()),与飞行管理计算机的 solveSailLift / solveSailDirectionlessDrag 工具同源。

游戏气动 ≠ 现实气动:三条根本差异

先记住这三条,所有"位置规则"都由它们推出,不是航空学搬运:

  1. 力的方向是"机体固定"的,不随气流方向翻转

    现实:翼型升力垂直于气流、随攻角连续改向。游戏:普通帆升力恒沿帆面法线 +n,对称帆阻力沿 ±n,无方向阻尼沿 -v。→ 帆的摆向决定力的方向:倒扣时机翼升力朝下压。

  2. 力的大小 ∝ 局部气流速度(线性),不是 v²

    现实:动压 q = ½ρv²。游戏:每块帆 F ≈ k·P·Δt·v。→ 低速气动力线性衰减;速度为零就没有任何气动力。

  3. 攻角(α)效应只来自 (n·v) 项,且只有对称帆/法向阻力是"奇函数"

    普通帆升力随 (n·v)² 减小(偶函数,对 ±α 对称);对称帆法向阻力是 (n·v) 线性项(奇函数,抬头/低头扰动产生方向相反、大小对称的恢复力)。

→ 推论:现实"重心在气动中心之前 → 静稳定"依赖机翼升力随 α 增长,游戏里普通帆升力对 ±α 对称减小,这条规则不能照搬。游戏里真正提供双向静稳定的是奇函数面(对称帆法向阻力)放在重心后方——它像风向标/α 弹簧,把机体拉回与气流对齐。


通用公式:每块帆每个物理子步都算一次

每个物理子步 Δt、每块帆,算法骨架相同(参数不同,见下两节):

  1. 法线 n:风帆 = FACING 反方向;对称风帆 = AXIS 正方向。帆在 contraption 里时先经 localPose 旋转到子层级坐标系。
  2. 局部气流速度(在帆方块中心取):
    v = R⁻¹( 整机线速度 V + 角速度 ω × (方块中心 − 子层级原点) )
    
    → 远离重心的帆会"感受到"旋转,自动产生气动阻尼。
  3. 该处气压 P:DimensionPhysicsData.getAirPressure(...),随高度按维度压力曲线衰减(主世界 300 m ≈ 0.39)。
  4. 法向阻力(沿帆面法线):大小 = k1·|n·v|·P·Δt,施加到机体取负 → 抵消速度在帆面法线上的分量。
  5. 无方向阻力(线性阻尼,与 v 反向):大小 = k2·|v|·P·Δt,恒抵消速度。
  6. 升力(仅普通帆有,见下):方向恒沿 +n,大小 = k3·|TEMP|·P·Δt。
  7. 施力点 = 帆方块中心(pos+0.5),力矩 τ = (施力点 − 重心) × 力 → 帆离重心越远,同样力产生的力矩越大。

Create 普通帆(风帆):升力 + 阻力

由 Create 兼容 mixin(SailBlockMixin)注入接口,参数全用 Sable 默认值:

参数 值 含义
法线 n FACING 反方向 升力/法向阻力的轴向
升力系数 k3 0.475 普通帆才产生升力
法向阻力系数 k1 0.75 垂直帆面的阻力
无方向阻力系数 k2 0.06888202261 线性阻尼((−0.75+√(0.75²+0.475²))/2,恰好压住默认升力发散的最小阻尼)

每个物理子步的算法:

  1. 法向阻力(k1 = 0.75):F_par = n·(n·v)·0.75·P·Δt,施加到机体取负 → 抵消速度在法线上的分量;大小 = |n·v|·0.75·P·Δt。
  2. 无方向阻力(k2):与 v 反向,大小 = |v|·0.06888·P·Δt。
  3. 升力(普通帆核心输出,k3 = 0.475):
  4. 先从速度里扣掉已被法向阻力吃掉的部分:TEMP = v − F_par 矢量
  5. 大小 = |TEMP|·0.475·P·Δt(≈ 随该处局部气流速度增长)
  6. 方向 = 恒沿 n(FACING 反方向),没有 (n·v) 那样的符号翻转——帆永远被往 n 那一侧推。
  7. 施力点 = 帆方块中心,力矩 = (施力点 − 重心) × 力。

对设计的直接含义:

  • 普通帆 = "升力为主"的升力面。升力方向固定在帆自身坐标系(n 侧),随机体一起转动——机体倒扣时 n 朝下 → 升力也朝下(压向地面);只有姿态摆正、n 侧朝上才是可靠升力。
  • 升力/阻力大小都 ∝ 该处局部气流速度 |v|(线速度 + 角速度×力臂)→ 帆离重心越远,同样的机体运动产生更大的力与力矩(阻尼、配平、控制都靠这个)。
  • 全部力受 P(维度气压 basePressure × 高度曲线)整体缩放。

对称风帆(Symmetric Sail):只产生阻力

Simulated 的 SymmetricSailBlock 不算力,只是 Sable BlockSubLevelLiftProvider 接口的实现,参数覆写为:

参数 对称风帆 普通帆(默认) 含义
法线 n AXIS 正方向 FACING 反方向 帆面法线
升力系数 k3 0(覆写) 0.475 对称帆不产生升力
法向阻力系数 k1 1.75(覆写) 0.75 垂直帆面的阻力(2.3 倍)
无方向阻力系数 k2 0.06888202261(未覆写) 0.06888202261 线性阻尼

每个物理子步的算法:

  1. 法向阻力(对称帆的主力):大小 = |n·v|·1.75·P·Δt,方向沿法线 n、符号跟随 (n·v),施加到机体取负 → 效果永远是"抵消速度在帆面法线上的分量"。
  2. n·v = 0(气流顺着帆面)时此项为 0,帆"没有效果";偏转出角度阻力才出现 → 舵面/安定面因此能产生控制力矩。
  3. 无方向阻力(k2):与 v 反向,大小 = |v|·0.06888·P·Δt(恒抵消线速度)。
  4. 升力 = 0 → 对称帆只产生阻力(这正是它名字的由来)。
  5. 施力点 = 帆方块中心,力矩 = (施力点 − 重心) × 力。

对设计的直接含义:

  • 对称帆 = 纯阻力/阻尼面:尾翼越大、离重心越远,俯仰/偏航阻尼越强、飞机越"稳",但也会更迟钝。
  • 对称帆 = "风向标式 α 弹簧":法向阻力 (n·v) 是奇函数,抬头/低头扰动产生方向相反的恢复力——只要放在重心后方,光靠对称帆尾翼就能提供双向静稳定,不需要"升力中心在重心之后"。刚度 ∝ k1·P·V·力臂(高空/低速时刚度自动变弱)。
  • 1.75 是普通帆法向系数(0.75)的 2.3 倍,且升力为 0 → 对称帆偏转后阻力方向改变 → 产生控制力矩(官方 ponder:尾部对称帆 + 旋转轴承 30° 就是方向舵)。
  • 整个阻力受 P 缩放:改维度 dimension_physics 数据包的气压/高度曲线,会整体缩放所有帆的阻力(和普通帆的升力)。

别忘了:通用阻力(universal drag)

上述都是"帆"的力。除此之外,Rapier 还给每个物理体施加恒定速度阻尼(默认 d = 0.09),直接衰减刚体速度、不经过力组——图纸和记录器都看不到它。等效力:

F = −m·d·v   (与速度成正比、与质量成正比、不乘气压 P)

巡航时它通常是最大的阻力项(比帆阻力还大近一倍),做净力平衡(推力 − 帆阻力 − 通用阻力 ≈ 0)时必须补上。详见飞行管理计算机的"通用阻力"一节与 getUniversalDragForce 工具。


相关页面

  • 飞行管理计算机 — solveSailLift / solveSailDirectionlessDrag / getUniversalDragForce / solveMaxCruise 工具
  • 教练机 — 应用这些规则设计的可飞示例