Underdamped spring formula changed
Summary
#The formula for SpringDescription
changed to correct an earlier error,
affecting underdamped springs (damping ratio less than 1)
with mass values other than 1.
Springs created prior to this change may exhibit
different bouncing behaviors after upgrading.
Background
#The SpringDescription
class describes the behavior of damped springs,
enabling Flutter widgets to animate realistically based on provided parameters.
The physics of damped springs are widely studied and documented. For an overview
of damping, see Wikipedia: Damping.
Previously, Flutter's formula for calculating underdamped spring behavior was
incorrect, as reported in Issue 163858. This error affected all springs with
a damping ratio less than 1 and a mass other than 1. Consequently, animations
did not match expected real-world physics, and behavior around the critical
damping point (damping ratio of exactly 1) exhibited discontinuities.
Specifically, when using SpringDescription.withDampingRatio
, small
differences, such as damping ratios of 1.0001 versus 0.9999, resulted in
significantly different animations.
The issue was corrected in PR Fix SpringSimulation formula for underdamping, which updated the underlying calculation. As a result, previously affected animations now behave differently, though no explicit errors are reported by the framework.
Migration guide
#Migration is necessary only for springs with damping ratios less than 1 and masses other than 1.
To restore previous animation behavior, update your spring parameters accordingly. You can calculate the required parameter adjustments using the provided JSFiddle for migration. Detailed formulas and explanations follow in the next sections.
Default constructor
#If the SpringDescription
was built with the default constructor with mass m
, stiffness k
, and damping c
,
then it should be changed with the following formula:
new_m = 1
new_c = c * m
new_k = (4 * (k / m) - (c / m)^2 + (c * m)^2) / 4
Code before migration:
const spring = SpringDescription(
mass: 20.0,
stiffness: 10,
damping: 1,
);
Code after migration:
const spring = SpringDescription(
mass: 1.0,
stiffness: 100.499375,
damping: 20,
);
.withDampingRatio
constructor
#If the SpringDescription
was built with the .withDampingRatio
constructor with mass m
, stiffness k
, and ratio z
,
then first calculate damping
c = z * 2 * sqrt(m * k)
Then apply the formula above. Optionally you might convert the result back to damping ratio with
new_z = new_c / 2 / sqrt(new_m * new_k)
Code before migration:
const spring = SpringDescription.withDampingRatio(
mass: 5.0,
stiffness: 6.0,
damping: 0.03,
);
Code after migration:
const spring = SpringDescription.withDampingRatio(
mass: 1,
stiffness: 1.87392,
ratio: 0.60017287468545,
);
Timeline
#Landed in version: 3.31.0-0.1.pre
In stable release: Not yet
References
#API documentation:
Relevant issues:
- Issue 163858, where the bug was discovered and more context can be found.
Relevant PRs:
Tool:
除非另有说明,本文档之所提及适用于 Flutter 的最新稳定版本,本页面最后更新时间: 2025-03-24。 查看文档源码 或者 为本页面内容提出建议.