尧图精选

为什么直接lerp坐标会让图标变形塌陷?morphicons极坐标插值原理与弹簧超调外推数学解析

🕒 发布时间:2026/10/1 21:30:07 📁 来源:尧图网络
为什么直接lerp坐标会让图标变形塌陷morphicons极坐标插值原理与弹簧超调外推数学解析【免费下载链接】morphiconsAny icon morphs into any other — universal morphing for stroke-based icons with spring physics. Zero dependencies, ~7 KB gzip.项目地址: https://gitcode.com/gh_mirrors/mo/morphicons做图标变形动画icon morphing时最直觉的做法是对两个图标的每个点做线性插值P(t) (1−t)·A t·B。但你会发现动画进行到一半时图标会收缩、扭曲、塌陷像被橡皮泥捏过一样。morphicons 正是为了解决这个问题而生的图标变形动画库——它用**极坐标插值polar interpolation**在旋转与缩放的自然空间里做动画再用弹簧物理spring physics驱动进度让任何描边图标都能变成任何其它图标。这篇文章把背后的数学拆解给你看。一、直接 lerp 坐标图标为什么会在半路塌掉先看一个经典场景把向右箭头arrow-right变成向下箭头arrow-down。这两个图标在几何上只差一次90° 旋转——箭头尖、箭杆的每个点在旋转意义下都是严格对应的。可如果直接对坐标 lerp每一点会沿着**直线弦**飞向目标位置箭头尖本来应该绕箭杆走一段圆弧现在却被拽着直线穿墙中点帧里旋转分量还没转到位而坐标分量已经平移了一大半两种运动互相打架形状既不在 A 上、也不在任何旋转后的 A 上而是被**剪切shear 压缩shrink**成一个怪形状描边图标尤其明显线条的粗细观感来自几何一旦被挤压线条会看起来变粗、打结、塌陷。这就是项目 README 里说的经典病症interpolate raw coordinates (shapes shrink and shear in transit)。直接 lerp 还隐含第二个坑对应关系错了。A 图标的第 3 个点在 B 图标里对应的可能根本不是第 3 个点起点不同、绕行方向不同、路径数还不一样。对应错了再平滑的插值也只会得到一团乱线。二、对齐与对应先给每个点找到正确的伙伴morphicons 的管线是normalize → resample → match → align → plan → interpolate(t) → d其中前三步全是为插值铺路。步骤做什么源码归一化把 line/circle/rect/arc 等 SVG 基元统一降阶为三次贝塞尔曲线圆弧按 SVG 规范 F.6 切成 ≤90° 的弧片KAPPA 4/3·tan(π/8) ≈ 0.5523src/core/normalize.ts重采样用 8 点 Gauss-Legendre 数值积分弧长把每条子路径等弧长重采样成固定 N 个点拐角切线跳变 22.5°作为锚点精确保留src/core/resample.ts配对子路径之间用质心距离 0.35·|长度差|做代价矩阵求最优配对条数不等时用满射分配——多出来的源路径折叠到同一目标像细胞分裂而不是凭空消失src/core/plan.ts对齐对每对子路径尝试两种绕行方向 闭合环的 N 个循环起点偏移用闭式2D Procrustes求最优相似变换src/core/plan.tsProcrustes 是这里的关键它求的是让Σ|σ·R(θ)·(a−c_A) − (b−c_B)|²最小的相似变换旋转 θ 缩放 σ而且不需要 SVD一次atan2出结果θ* atan2(Sxy − Syy, Sxx Syy)σ* 由零导数条件直接给出见 src/core/plan.ts 的procrustes函数测试套件把它钉成了可执行的规格test/invariants.test.tsarrow-right → arrow-down 的两条子路径都独立算出 θ 90°、σ 1、残差 1e-6plus → x 算出 45° 旋转 σ ≈ 1.212。也就是说旋转不是人肉声明的是数学自己算出来的。三、极坐标插值在相似变换的自然空间里动拿到 (θ, σ) 之后morphicons 不插值坐标而是插值相似变换本身——角度线性、缩放对数线性、质心平移最后作用在对齐后的残差混合上。核心公式src/core/interpolate.tsP(t) c(t) σᵗ · R(t·θ) · [(1−t)·aC t·bT]其中aC是 A 减去质心的点云bT是 B 被搬进 A 坐标系后的点云R(−θ)·(b−c_B)/σ。逐项拆开看为什么它不会塌陷σᵗ e^{t·lnσ}缩放是乘法运算在 log 空间里才是线性的。t 从 0→1σ 从 1 平滑地指数滑向目标值不会忽快忽慢R(t·θ)旋转按角度线性推进。若两图标只差旋转残差 res ≈ 0残差混合那一项在任意 t 下形状几乎不变整个图标就是刚体旋转——箭头绕着自己转 90°而不是被弦线拖着走[(1−t)·aC t·bT]只有两个形状真正不相似的那部分残差才做线性混合而它已经被搬进了对齐坐标系里混合幅度最小t 0 和 t 1 精确成立测试要求两端点误差 1e-9见 test/invariants.test.ts 的 invariant 4动画首尾与静态图标完全一致。还有一个精妙的细节叫全局混合global hybrid 块状运输如果整个图标在一个统一相似变换下全等所有子路径共享同一组 (θ, σ)而且子路径的质心不做普通 lerp——质心会搭乘这个共享相似变换绕全局质心走圆弧src/core/plan.ts 中block字段。源码注释说得很直白如果质心走弦线会走进弧线内侧箭头的尖会在半路塌向箭杆。质心绕弧走图标全程保持刚体。四、弹簧超调t 1 时公式如何自然外推进度 t 不是由缓动曲线给的而是由一个阻尼谐振子积分出来的src/core/spring.tsẍ k·(1−x) − c·ẋ用半隐式欧拉法按 1/240 秒子步积分数值稳定裕量充足三个内置预设对应不同阻尼比 ζ c/(2√k)预设k / c阻尼比 ζ手感smooth170 / 261.00临界阻尼不超调平滑落定snappy420 / 300.73快轻微超调bouncy300 / 140.40俏皮明显回弹欠阻尼弹簧ζ 1会让进度 x冲过 1 再弹回来——也就是 t 会短暂大于 1。这正是极坐标公式设计的用武之地把 t 1 直接代入P(t) c(t) e^{t·lnσ} · R(t·θ) · [(1−t)·aC t·bT]三项全部沿物理意义方向自然外推角度 t·θ 转过 90° 再往回摆——图标多转几度又转回来缩放 e^{t·lnσ} 冲过目标尺寸再收缩残差项 (1−t)·aC t·bT 沿 A→B 方向延伸出 B 之后的一小段。没有任何 if/else 钳位公式在 t 1 区域解析地平滑得到的就是橡皮筋拉过头再弹回的超调动画。这就是弹簧超调外推的全部秘密把超调留给弹簧把形状交给解析公式。这套机制还免费获得了可打断性飞行途中再次 morphTo 时弹簧保留速度钳位在 ±14从零重启计划从当前中间形状重建——疯狂连点也不会跳变。test/invariants.test.ts 的 invariant 7 专门模拟了连续 4 次中途改目标要求全程无 NaN、速度连续、最终精确落定。五、把这套数学用进自己的项目如果你用 React/Vue/Svelte/React Native 绑定这些数学都是零配置的import { MorphIcon } from morphicons/react; import { Menu, X } from lucide; // 图标是数据不是组件 MorphIcon icon{open ? X : Menu} springsnappy /而如果你想亲手调管线纯核心无 DOM 依赖gzip 约 7 KB暴露了全部数学环节见 src/index.tsresampleIcon → buildPlan → interpPolar(plan, t, out) → serializet 由你任意给——包括大于 1 的超调值。interpLinear也保留着专门用来和极坐标模式做视觉对比。延伸阅读架构决策 docs/adr/0001-frozen-core-contracts-adapters-entry.md 解释了核心为什么冻结在两个契约上实验场 morphicons-spike.html 和 playground/ 可以直接打开看插值效果。小结直接 lerp 塌陷的根因坐标空间里的直线混合与旋转缩放的几何运动正交——弦线穿过内部形状被剪切压缩极坐标插值的解法闭式 Procrustes 求出最优相似变换在角度/对数缩放/质心的自然空间里插值刚体对保持刚体残差在对齐系里混合端点精确弹簧超调的魔法欠阻尼谐振子让 t 短暂 1而解析公式在外推区域依然光滑超调动画免费获得还天然支持中途打断重规划。理解了这个公式你下次写任何形变动画时都会知道为什么先分解再插值最后合成永远是比直接 lerp更好的一条路。【免费下载链接】morphiconsAny icon morphs into any other — universal morphing for stroke-based icons with spring physics. Zero dependencies, ~7 KB gzip.项目地址: https://gitcode.com/gh_mirrors/mo/morphicons创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →