本文将介绍如何使用ManimCE
框架实现一个水波纹特效,让你的数学动画更加生动有趣。
水波纹特效通过WaterRipple
类实现,这是一个自定义的Animation
子类。让我们从代码角度来分析其实现原理:
class WaterRipple(Animation):
def __init__(
self, mobject, scene=None, num_ripples=5, max_outer_radius=3,
min_inner_radius=1, run_time=2, wave_speed=1.0,
color=BLUE, fade_out=True, **kwargs
):
# 初始化参数设置
self.num_ripples = num_ripples
self.max_outer_radius = max_outer_radius
self.min_inner_radius = min_inner_radius
self.wave_speed = wave_speed
self.color = color
self.fade_out = fade_out
self.ripples = []
self.mobject = mobject
self.scene = scene
# 颜色处理逻辑
self.color_list = color if isinstance(color, list) else [color] * num_ripples
if len(self.color_list)
从代码中可以看出,WaterRipple
类采用了以下核心设计:
Annulus
(圆环)作为基本波纹单元,通过self.ripples
列表存储多个波纹对象scene
参数,方便将波纹直接添加到场景中动画的核心在于interpolate_mobject
方法,它定义了动画如何随时间变化:
def interpolate_mobject(self, alpha: float) -> None:
# 计算每个波纹的半径和透明度
for i in range(self.num_ripples):
# 每个波纹有不同的相位偏移
phase_offset = i * (np.pi / self.num_ripples)
# 使用正弦函数计算半径和透明度,实现波动效果
time_progress = (alpha + phase_offset * 0.2) % 1
radius = self.max_outer_radius * time_progress
if self.fade_out:
# 透明度随半径增大而减小,使用正弦函数使淡出更自然
opacity = max(0, np.sin(time_progress * np.pi))
else:
opacity = 1
# 应用变换,使用对应的颜色
new_c = Annulus(
inner_radius=self.min_inner_radius,
outer_radius=radius,
color=self.color_list[i],
stroke_width=2,
fill_opacity=opacity,
)
new_c.move_to(self.mobject.get_center())
self.ripples[i].become(new_c)
这里的关键技术点包括:
Annulus
对象并通过become()
方法更新波纹的状态动画结束后,需要清理创建的波纹对象:
def clean_up_from_scene(self, scene: Scene) -> None:
# 动画结束后清理波纹
for ripple in self.ripples:
if ripple in scene.mobjects:
scene.remove(ripple)
super().clean_up_from_scene(scene)
这个方法确保动画结束后不会在场景中留下多余的对象,保持场景的整洁。
下面通过一个完整的示例场景来展示如何使用水波纹特效:
# 示例场景:单个水波纹效果
class Example01(Scene):
def construct(self):
# 创建中心点
center_point = ORIGIN
center_dot = Dot(center_point, color=BLUE, radius=0.1)
self.play(FadeIn(center_dot))
self.wait()
# 应用水波纹动画,使用渐变色效果
# 创建颜色渐变列表,从蓝色到紫色再到红色
gradient_colors = [BLUE, TEAL, GREEN, YELLOW, RED]
self.play(
WaterRipple(
center_dot,
scene=self,
num_ripples=5,
max_outer_radius=2,
run_time=4,
wave_speed=1.2,
color=gradient_colors, # 使用渐变色列表
fade_out=True,
stroke_width=1,
)
)
self.wait(2)
from manim import *
import numpy as np
center_point = ORIGIN
center_dot = Dot(center_point, color=BLUE, radius=0.1)
self.play(FadeIn(center_dot))
gradient_colors = [BLUE, TEAL, GREEN, YELLOW, RED]
center_dot
:波纹中心点对象scene=self
:当前场景引用num_ripples=5
:波纹数量max_outer_radius=2
:最大半径run_time=4
:动画运行时间wave_speed=1.2
:波纹传播速度color=gradient_colors
:使用渐变色列表fade_out=True
:启用淡出效果根据实际需求,可以调整以下关键参数以获得不同的视觉效果:
num_ripples
:控制波纹数量,更多的波纹会使效果更密集max_outer_radius
:控制波纹扩散范围min_inner_radius
:控制波纹的最小内半径run_time
:控制动画持续时间wave_speed
:控制波纹传播速度color
:可以是单一颜色或渐变色列表fade_out
:是否启用淡出效果水波纹特效在以下场景中特别适用:
通过这个简单但功能强大的水波纹特效,可以为你的数学动画增添更多视觉吸引力和专业感。无论是教学演示、科学解释还是艺术创作,都能发挥重要作用。
参与评论
手机查看
返回顶部