你在制作Manim动画时,是否遇到过这样的困境?
“代码写得天衣无缝,运行流畅,出来的动画却总觉得哪里不对劲?”
虽然物体确实从 A 移动到了 B,但看起来就像是老旧的工业机器人在干活——僵硬、死板,甚至有点无聊。
其实,你的动画离 “丝滑” 和 “专业”,往往只差这一个参数的距离:rate_func (速率函数)。
今天,我们就来聊聊 Manim 中这个不起眼但至关重要的参数,看看如何通过控制 “时间的流速”,让你的数学动画不仅能动,而且动得有节奏、有灵魂。
在 Manim 中,当你写下 .animate.shift(RIGHT) 时,默认发生了什么?
如果你觉得动画只是简单的“在 Run Time 时间内移动距离 RIGHT”,那只对了一半。Rate Function 本质上是动画完成度与时间的关系。
想象一下你在看视频时的进度条:
默认的魔法:Smooth
Manim 的默认 rate_func 是 smooth。
这符合物理世界的惯性定律:起步时慢(加速),中间快,快结束时慢(减速)。
这就是为什么默认的动画看起来比较自然。
如果我们把它换成 linear(线性),物体就会瞬间以最大速度启动,最后瞬间急停,看起来就会很像 “PPT 动画”。
Manim内置了一大堆写好的函数,位于 manim.utils.rate_functions。
我们可以把它们看作是给动画调味的香料。
为了方便演示,我们假设我们要移动一个小球。
linear (匀速)
smooth (默认)
rush_into / rush_from
rush_into: 越走越快,最后“砰”地撞线(只有加速)。rush_from: 一开始很快,慢慢停下来(只有减速)。rush_from),或者发射出去(rush_into)。there_and_back (往返)
wiggle (摆动)
running_start (助跑)
ease_out_bounce(落地反弹)
光说不练假把式。下面的示例代码可以直观感受不同函数的区别:
from manim import *
class RateFuncComparison(Scene):
def construct(self):
# 定义我们想对比的函数
funcs = [
linear,
smooth,
rush_from,
rush_into,
there_and_back,
rate_functions.ease_out_bounce,
]
labels = [
"Linear",
"Smooth",
"Rush Into",
"Rush From",
"There & Back",
"Bounce",
]
# 创建圆点和文字
group = VGroup()
for i, (func, label_text) in enumerate(zip(funcs, labels)):
dot = Dot(color=TEAL)
label = Text(label_text, font_size=20).next_to(dot, LEFT)
row = VGroup(label, dot)
group.add(row)
# 竖直排列
group.arrange(DOWN, buff=0.5).to_edge(LEFT)
self.add(group)
# 制作动画:让所有点同时向右移动
# 注意:我们在这里分别指定了不同的 rate_func
anims = []
for item, func in zip(group, funcs):
dot = item[1] # 获取组里的 Dot
anims.append(dot.animate(rate_func=func, run_time=3).shift(RIGHT * 4))
self.play(*anims)
运行后你会发现,虽然大家的 run_time 都是3秒,移动距离一样,但“性格”截然不同。

作为会 Python 的老手,如果内置函数满足不了你怎么办?
rate_func 接受任何一个 Python 函数。
比如,你想做一个简单的“先慢后快”的加速效果,可以直接用 Lambda:
# y = x^2,典型的加速曲线
class CustomRateFuncDemo(Scene):
def construct(self):
# 创建一个圆
circle = Circle(radius=0.5, color=BLUE).shift(LEFT * 2)
self.add(circle)
# 使用自定义 rate_func(t**2)让圆向右移动
self.play(circle.animate(rate_func=lambda t: t**2).shift(RIGHT * 4), run_time=3)
self.wait()

这是 Manim 中最强大的黑科技之一:squish_rate_func。
假设你写了一个 run_time=6 的动画,但你希望某个特定的变换(比如变色),
在第 1.2 秒到第 3 秒之间(即整个进度的 0.2 到 0.5)由白色变成红色;
在第 3 秒到第 4.8 秒之间(即整个进度的 0.5 到 0.8)由红色变成绿色。
你不需要把动画拆成多段写,只需要:
class SquishRateFuncDemo(Scene):
def construct(self):
# 创建一个圆点
dot = Dot(color=WHITE).shift(LEFT * 2)
self.add(dot)
# 使用UpdateFromAlphaFunc来同时控制位置和颜色变化
def update_dot(obj, alpha):
# 位置变化 - 使用默认的linear速率
obj.move_to(LEFT * 2 + RIGHT * 5 * alpha)
# 颜色变化 - 使用squish_rate_func控制变色的时间段
squished_alpha = squish_rate_func(smooth, 0.2, 0.5)(alpha)
squished_alpha2 = squish_rate_func(smooth, 0.5, 0.8)(alpha)
if alpha
这个技巧在制作复杂的多重同步动画时非常有效!

Manim 不仅仅是动画工具,它更像是一个导演工具。
linear 是为了表现机械、循环。smooth 是为了表现自然、物理。there_and_back / wiggle 是为了引导观众的注意力。squish_rate_func 是为了精准控制时间轴。下次当你的动画看起来略显生硬时,不妨停下来想一想:“这个动作的节奏对吗?是不是该换个 rate function 了?”
登录查看全部
参与评论
手机查看
返回顶部