概述

#

SpringDescription 的公式已更改,以纠正之前的错误,此更改会影响质量值非 1 的欠阻尼弹簧(阻尼比小于 1)。在此更改之前创建的弹簧在升级后可能会表现出不同的回弹行为。

背景

#

SpringDescription 类描述了阻尼弹簧的行为,使 Flutter 小部件能够根据提供的参数进行逼真的动画。阻尼弹簧的物理特性已被广泛研究和记录。有关阻尼的概述,请参阅 Wikipedia: Damping

此前,Flutter 计算欠阻尼弹簧行为的公式存在错误,如 Issue 163858 中所述。此错误影响了所有阻尼比小于 1 且质量非 1 的弹簧。因此,动画未能与预期的现实世界物理现象相匹配,并且在临界阻尼点(阻尼比正好为 1)附近的表现出现不连续。具体来说,在使用 SpringDescription.withDampingRatio 时,微小的差异,例如阻尼比为 1.0001 与 0.9999,导致动画产生显著差异。

该问题已在 PR Fix SpringSimulation formula for underdamping 中得到纠正,该 PR 更新了底层计算。因此,之前受影响的动画现在表现不同,尽管框架没有报告明确的错误。

迁移指南

#

仅当弹簧的阻尼比小于 1 且质量非 1 时,才需要迁移。

要恢复之前的动画行为,请相应地更新您的弹簧参数。您可以使用提供的 JSFiddle for migration 来计算所需的参数调整。详细的公式和解释将在接下来的部分中给出。

默认构造函数

#

如果 SpringDescription 是使用默认构造函数、质量 m、刚度 k 和阻尼 c 构建的,则应使用以下公式进行更改:

new_m = 1
new_c = c * m
new_k = (4 * (k / m) - (c / m)^2 + (c * m)^2) / 4

迁移前的代码

dart
const spring = SpringDescription(
  mass: 20.0,
  stiffness: 10,
  damping: 1,
);

迁移后的代码

dart
const spring = SpringDescription(
  mass: 1.0,
  stiffness: 100.499375,
  damping: 20,
);

.withDampingRatio 构造函数

#

如果 SpringDescription 是使用 .withDampingRatio 构造函数、质量 m、刚度 k 和比率 z 构建的,则首先计算阻尼:

c = z * 2 * sqrt(m * k)

然后应用上述公式。可选地,您可以使用以下方法将结果转换回阻尼比:

new_z = new_c / 2 / sqrt(new_m * new_k)

迁移前的代码

dart
const spring = SpringDescription.withDampingRatio(
  mass: 5.0,
  stiffness: 6.0,
  damping: 0.03,
);

迁移后的代码

dart
const spring = SpringDescription.withDampingRatio(
  mass: 1,
  stiffness: 1.87392,
  ratio: 0.60017287468545,
);

时间线

#

已合并到版本:3.31.0-0.1.pre
稳定版本:3.32

参考资料

#

API 文档

相关问题

  • Issue 163858,此处发现了错误并可找到更多上下文。

相关 PR

工具