Manim实现旋转变色特效

笔记哥 / 05-30 / 5点赞 / 0评论 / 382阅读
在数学动画的世界里,**旋转与变色**特效无疑是最能吸引观众眼球的元素之一。 今天,就让我们一起探索如何使用`Manim`框架来实现自定义的旋转变色特效吧! # 1. 实现原理 `Manim`的动画魔法源于`Animation`类的`interpolate_mobject`方法。 这个方法通过`alpha`参数(**0到1之间**)控制动画进度,我们只需重写这个方法就能创造自定义特效: ```python class RotateAndColor(Animation): def __init__( self, mobject, angle=TAU, start_color=BLUE, end_color=RED, about_point=ORIGIN, **kwargs ): """ 构造函数。 Parameters: mobject - 这是要进行动画的对象,例如一个几何形状、文本或其他任何 Manim 支持的对象 angle - 指定旋转的总角度,默认值为 TAU 即 360度 start_color - 动画开始时对象的颜色,默认蓝色 end_color - 动画结束时对象的颜色,默认为红色 **kwargs - 用于传递额外的关键字参数到父类Animation的构造函数中 """ # 调用父类Animation的构造函数, # 将mobject和额外的关键字参数传递给父类,完成基本的初始化 super().__init__(mobject, **kwargs) # 将传入的参数存储为类的属性,以便后续使用 self.angle = angle self.start_color = start_color self.end_color = end_color self.about_point = about_point def interpolate_mobject(self, alpha): """ 实现动画效果的核心方法。 Parameters: alpha - 是一个介于 0 和 1 之间的参数,表示动画的进度 """ pass ``` 接下来,实现同一个动画周期内同时控制旋转和颜色: ```python def interpolate_mobject(self, alpha): """ 实现动画效果的核心方法。 Parameters: alpha - 是一个介于 0 和 1 之间的参数,表示动画的进度 """ # 颜色插值 # 使用interpolate_color函数计算当前进度alpha下的颜色 # interpolate_color是Manim中的一个内置函数,用于在两个颜色之间进行插值 new_color = interpolate_color(self.start_color, self.end_color, alpha) # 旋转角度计算 # 计算当前进度alpha下的旋转角度。 # 通过将alpha乘以总旋转角度self.angle,得到当前的旋转角度 current_angle = alpha * self.angle # 应用变换 # 将mobject重置为动画开始时的状态 self.mobject.become(self.starting_mobject) # 调用rotate方法,将mobject旋转current_angle角度, # 旋转的中心点是self.about_point self.mobject.rotate(current_angle, about_point=self.about_point) # 将mobject的颜色设置为当前插值计算得到的颜色 self.mobject.set_color(new_color) ``` 上面的代码中已经加了详细的注释,总得来说,`RotateAndColor`类实现了一个同时进行旋转和颜色变化的动画效果。 它通过继承`Animation`类,利用`Manim`的动画系统,实现了对对象的旋转和颜色变化。 通过`interpolate_mobject`方法,根据动画进度`alpha`,动态计算旋转角度和颜色,从而实现平滑的动画效果。 # 2. 应用示例 实现了这个自定义的旋转变色动画(`RotateAndColor`)后,下面来实际使用看看效果如何。 ## 2.1. 基础使用 在基础使用示例中,我们构造一个正方体,先快速旋转3圈,同时颜色由蓝变绿; 再慢速旋转半圈,同时颜色又绿变紫。 ```python class RotateColorSample01(ThreeDScene): def construct(self): self.set_camera_orientation(phi=75 * DEGREES, theta=-45 * DEGREES) cube = Cube().set_fill(BLUE, opacity=0.8) self.play( RotateAndColor( cube, angle=3 * TAU, # 旋转3圈 start_color=BLUE, end_color=GREEN, run_time=2, ) ) self.wait() # 添加对比动画 self.play( RotateAndColor( cube, angle=TAU / 2, # 仅转半圈 start_color=GREEN, end_color=PURPLE, run_time=2, ) ) self.wait() ``` ![](https://cdn.res.knowhub.vip/c/2505/30/0d6cbddf.gif?G1MAAMTc2vOlOzc3s9%2fToCVYBtoMMKQRVKpZr2fvf51E%2fXUG53h9bUxfH35vYzodAigxWKEIQYCKKlU0h4RkzGYo0fsN) ## 2.2. 模拟公转自转 下面再构造一个略微复杂点的示例,构造两个球形模拟太阳和地球,太阳自转同时变色; 地球绕着太阳公转,且在绕的过程中逐渐变色(可用来模拟白天黑夜)。 ```python class RotateColorSample02(ThreeDScene): def construct(self): self.set_camera_orientation(phi=75 * DEGREES, theta=-45 * DEGREES) sun = Sphere(color=YELLOW).scale(1.2) earth = Sphere(resolution=24).scale(0.4).shift(RIGHT * 3) # 地球公转+太阳自转+色温变化 self.play( RotateAndColor( sun, angle=TAU / 2, start_color=YELLOW, end_color=RED, rate_func=there_and_back, ), RotateAndColor( earth, angle=TAU, start_color=BLUE, end_color=GREEN, about_point=sun.get_center(), rate_func=linear, ), run_time=8, ) self.wait() ``` ![](https://cdn.res.knowhub.vip/c/2505/30/7d70329d.gif?G1MAAMTc2vOlOzaXW7%2bnQUuwDLQZYEgjqFSzXs%2fe%2fzqJ%2bhsMLvn62pixPvzexgwyAZQYrFCkIIDDxaXUxFA3O7xKjn4D) # 3. 总结 通过上面介绍的方法,相信您已经掌握了制作专业级数学动画的核心技巧。 感兴趣的话,尝试修改示例代码中的参数,或者将旋转变色效果与缩放、位移等动画组合使用,创造出属于您的独特视觉效果!