如何消除Manim动画间时间间隔,实现流畅圆形运动模拟
解决Manim圆形运动动画间隔问题
你的问题出在每次调用self.play()时,Manim默认会在动画结束后添加短暂停顿,且分段调用move_to动画没有做到帧级别的连续衔接。以下是几种可行的解决方法:
方法1:关闭动画后的停顿
在self.play()中添加pause_after=0参数,取消每个动画播放后的默认停顿:
radii=[Rb/10, Rc/10, Rc/10] positions=positions/10 # 初始位置 i=0 initial_position = [ LEFT*positions[0,0,i]+UP*positions[0,1,i], LEFT*positions[1,0,i]+UP*positions[1,1,i], LEFT*positions[2,0,i]+UP*positions[2,1,i], ] circles = [Circle(color=BLUE, radius=radii[index], fill_opacity=1).shift(pos) for index,pos in enumerate(initial_position)] for circle in circles: self.add(circle) # 注意:初始位置已经是i=0,循环从i=1开始避免重复 for i in range(1, current_N): new_positions = [ LEFT*positions[0,0,i]+UP*positions[0,1,i], LEFT*positions[1,0,i]+UP*positions[1,1,i], LEFT*positions[2,0,i]+UP*positions[2,1,i], ] animations = [ circle.animate.move_to(new_pos) for circle, new_pos in zip(circles, new_positions) ] # 关闭动画后停顿 self.play(*animations, pause_after=0)
方法2:用Succession合并成连续动画序列
把所有移动动画合并成一个无缝衔接的序列,设置lag_ratio=0让动画连续播放:
radii=[Rb/10, Rc/10, Rc/10] positions=positions/10 i=0 initial_position = [ LEFT*positions[0,0,i]+UP*positions[0,1,i], LEFT*positions[1,0,i]+UP*positions[1,1,i], LEFT*positions[2,0,i]+UP*positions[2,1,i], ] circles = [Circle(color=BLUE, radius=radii[index], fill_opacity=1).shift(pos) for index,pos in enumerate(initial_position)] for circle in circles: self.add(circle) # 收集所有动画步骤 all_animations = [] for i in range(1, current_N): new_positions = [ LEFT*positions[0,0,i]+UP*positions[0,1,i], LEFT*positions[1,0,i]+UP*positions[1,1,i], LEFT*positions[2,0,i]+UP*positions[2,1,i], ] step_animations = [ circle.animate.move_to(new_pos) for circle, new_pos in zip(circles, new_positions) ] all_animations.extend(step_animations) # 用Succession播放,设置lag_ratio=0实现无缝衔接 self.play(Succession(*all_animations, lag_ratio=0))
方法3:用MoveAlongPath实现平滑连续路径(最优)
将每个圆形的所有位置点连成VMobject路径,让圆形沿着路径连续移动,这是最流畅的方式:
from manim import * radii=[Rb/10, Rc/10, Rc/10] positions=positions/10 i=0 initial_position = [ LEFT*positions[0,0,i]+UP*positions[0,1,i], LEFT*positions[1,0,i]+UP*positions[1,1,i], LEFT*positions[2,0,i]+UP*positions[2,1,i], ] circles = [Circle(color=BLUE, radius=radii[index], fill_opacity=1).shift(pos) for index,pos in enumerate(initial_position)] for circle in circles: self.add(circle) # 为每个圆形创建路径 paths = [] for circle_idx in range(3): # 收集该圆形的所有位置点 points = [] for i in range(current_N): point = LEFT*positions[circle_idx,0,i] + UP*positions[circle_idx,1,i] points.append(point) # 创建连续路径 path = VMobject() path.set_points_as_corners(points) paths.append(path) # 播放沿路径移动的动画,可统一设置run_time控制总时长 self.play( *[MoveAlongPath(circle, path, run_time=5) for circle, path in zip(circles, paths)], rate_func=linear # 线性运动更流畅,也可根据需求调整 )
关键注意点
- 初始位置已经使用了
i=0,循环要从i=1开始,避免重复播放初始位置的无意义动画。 - 如果需要更自然的运动,可以调整
rate_func参数,比如smooth或ease_in_out_sine。
内容的提问来源于stack exchange,提问作者eeqesri
相关产品推荐
相关产品推荐

