如何在Manim中实现扇形旋转与尺寸/角度同步动画?
如何在Manim中同步执行扇形的旋转与尺寸变化动画?
嘿,我完全懂你的困扰——Transform那种先收缩再扩张的过渡确实不是想要的,咱们要的是同一个扇形一边旋转一边平滑改变大小的同步效果对吧?其实不用找太复杂的API,直接通过动画化扇形的核心属性就能实现,下面给你两种可行的方案:
方案一:用ValueTracker精准控制同步节奏
这种方法通过一个进度变量统一驱动旋转和尺寸变化,能完全自定义动画的插值逻辑,灵活性最高:
from manim import * class Test(Scene): def construct(self): # 定义初始和目标状态的参数,以及旋转中心点 rotate_center = SmallDot().shift(RIGHT, DOWN) initial_angle = 45 * DEGREES initial_start = 25 * DEGREES target_angle = 135 * DEGREES target_start = 185 * DEGREES # 创建初始扇形并添加到场景 sector = Sector( angle=initial_angle, start_angle=initial_start, stroke_width=0, fill_color=RED ).shift(RIGHT, DOWN) self.add(rotate_center, sector) self.wait() # 用ValueTracker跟踪动画进度(0到1) progress = ValueTracker(0) def update_sector(mob): alpha = progress.get_value() # 线性插值计算当前的角度和起始角度 mob.angle = interpolate(initial_angle, target_angle, alpha) mob.start_angle = interpolate(initial_start, target_start, alpha) # 计算需要旋转的总角度:目标扇形的中心角度 - 初始扇形的中心角度 initial_center = initial_start + initial_angle / 2 target_center = target_start + target_angle / 2 total_rotate = target_center - initial_center # 应用旋转(基于当前进度) mob.rotate(alpha * total_rotate, about_point=rotate_center.get_center()) # 绑定更新函数到扇形,播放动画 self.play( progress.animate.set_value(1), UpdateFromFunc(sector, update_sector), run_time=2, rate_func=smooth ) self.wait()
方案二:用AnimationGroup同步多个基础动画
如果不需要自定义插值逻辑,直接把旋转动画和属性修改动画放到同一个AnimationGroup里,就能实现同步效果:
from manim import * class Test(Scene): def construct(self): rotate_center = SmallDot().shift(RIGHT, DOWN) sector = Sector( angle=45*DEGREES, start_angle=25*DEGREES, stroke_width=0, fill_color=RED ).shift(RIGHT, DOWN) self.add(rotate_center, sector) self.wait() # 计算总旋转角度 initial_center = 25*DEGREES + 45*DEGREES/2 target_center = 185*DEGREES + 135*DEGREES/2 total_rotate = target_center - initial_center # 同步播放旋转、角度修改、起始角度修改动画 self.play( Rotating( sector, axis=OUT, about_point=rotate_center.get_center(), radians=total_rotate ), ApplyMethod(sector.set_angle, 135*DEGREES), ApplyMethod(sector.set_start_angle, 185*DEGREES), run_time=2, rate_func=smooth ) self.wait()
关键思路说明
- 扇形的尺寸由
angle(扇形角度)和start_angle(起始角度)共同决定,直接修改这两个属性就能实现尺寸变化,不需要创建新的扇形实例。 - 旋转动画通过
Rotating或者直接调用rotate()方法实现,核心是确保旋转的进度和尺寸变化的进度完全同步——两种方案都是通过统一的run_time和rate_func来保证这一点的。
内容的提问来源于stack exchange,提问作者Doc Octal




