Manim实现荡漾扩散殊效

[复制链接]
发表于 昨天 14:22 | 显示全部楼层 |阅读模式
在视频制作和数据可视化范畴,荡漾扩散殊效是一种常见且富有视觉吸引力的动画效果。
本文将具体先容怎样利用Manim数学动画引擎来实现这一效果,包罗着实现原理、利用示例以及应用场景。
1. 实现原理

荡漾扩散殊效重要通过RippleEffect类来实现,该类继续自Manim的Animation基类。让我们深入相识其核心实现机制:
1.1. 核心筹划思绪
  1. class RippleEffect(Animation):
  2.     """
  3.     涟漪扩散特效动画类
  4.    
  5.     实现方法:使用Circle类创建多个同心圆,然后通过发光层实现发光效果,
  6.     再利用脉冲效果实现闪烁,从而模拟涟漪的扩散和闪烁。
  7.     """
复制代码
1.2. 参数筹划

该类提供了丰富的参数控制,使其具有高度可定制性:
  1. def __init__(
  2.     self,
  3.     mobject: Mobject,
  4.     num_ripples: int = 5,
  5.     max_radius: float = 3.0,
  6.     min_radius: float = 0.1,
  7.     ripple_speed: float = 1.0,
  8.     color: ParsableManimColor = BLUE,
  9.     fade_out: bool = True,
  10.     glow_num: int = 3,
  11.     glow_width: float = 5,
  12.     pulse_frequency: float = 2.0,
  13.     **kwargs
  14. ):
  15.     # 存储参数
  16.     self.num_ripples = num_ripples
  17.     self.max_radius = max_radius
  18.     self.min_radius = min_radius
  19.     self.ripple_speed = ripple_speed
  20.     self.color = color
  21.     self.fade_out = fade_out
  22.     self.glow_num = glow_num
  23.     self.glow_width = glow_width
  24.     self.pulse_frequency = pulse_frequency
复制代码
1.3. 多颜色支持实现

代码奇妙地支持单色和多色两种模式:
  1. # 处理颜色参数,支持单个颜色或多个颜色
  2. if isinstance(color, (list, tuple)):
  3.     self.colors = list(color)
  4.     self.use_multiple_colors = True
  5. else:
  6.     self.colors = [color]
  7.     self.use_multiple_colors = False
复制代码
1.4. 荡漾对象初始化

在构造函数中,代码预先创建了全部必要的荡漾圆环和对应的发光层:
  1. # 创建涟漪圆环列表
  2. self.ripples = []
  3. self.glow_layers = []
  4. # 创建多个同心圆环作为涟漪
  5. for i in range(num_ripples):
  6.     # 确定当前涟漪的颜色
  7.     if self.use_multiple_colors:
  8.         ripple_color = self.colors[i % len(self.colors)]
  9.     else:
  10.         ripple_color = self.colors[0]
  11.     # 使用Circle创建圆环,初始半径为最小半径
  12.     circle = Circle(
  13.         radius=min_radius,
  14.         stroke_color=ripple_color,
  15.         stroke_width=2,
  16.         fill_opacity=0,
  17.     ).move_to(mobject.get_center())
  18.     self.ripples.append(circle)
  19.     # 为每个涟漪创建发光层
  20.     glow_group = []
  21.     for j in range(glow_num):
  22.         glow = circle.copy()
  23.         glow_group.append(glow)
  24.     self.glow_layers.append(glow_group)
复制代码
1.5. 动画插值实现

interpolate_mobject方法是实现动画效果的核心,它在每一帧都会被调用:
  1. def interpolate_mobject(self, alpha: float):
  2.     """
  3.     实现动画效果的核心方法
  4.    
  5.     Parameters:
  6.         alpha - 是一个介于 0 和 1 之间的参数,表示动画的进度
  7.     """
  8.     # 计算时间进度,考虑涟漪速度
  9.     time_alpha = alpha * self.ripple_speed
  10.     # 为每个涟漪计算不同的相位偏移,创建连续的涟漪效果
  11.     for i, (ripple, glow_group) in enumerate(zip(self.ripples, self.glow_layers)):
  12.         # 确定当前涟漪的颜色
  13.         if self.use_multiple_colors:
  14.             ripple_color = self.colors[i % len(self.colors)]
  15.         else:
  16.             ripple_color = self.colors[0]
  17.         # 计算每个涟漪的相位偏移
  18.         phase_offset = i / self.num_ripples
  19.         # 计算当前涟漪的时间进度
  20.         ripple_time = (time_alpha + phase_offset) % 1
  21.         # 计算当前半径,从最小半径到最大半径
  22.         current_radius = interpolate(self.min_radius, self.max_radius, ripple_time)
  23.         # 计算透明度,如果启用淡出效果
  24.         if self.fade_out:
  25.             # 使用正弦函数创建自然的淡出效果
  26.             opacity = np.sin(ripple_time * PI) * 0.8
  27.         else:
  28.             opacity = 0.8
  29.         # 确保透明度不为负数
  30.         opacity = max(0, opacity)
  31.         # 添加脉冲效果
  32.         pulse_effect = np.sin(ripple_time * self.pulse_frequency * 2 * PI) * 0.2
  33.         opacity = max(0, opacity + pulse_effect)
  34.         # 创建新的圆环并更新属性
  35.         new_ripple = Circle(
  36.             radius=current_radius,
  37.             stroke_color=ripple_color,
  38.             stroke_width=2,
  39.             stroke_opacity=opacity,
  40.             fill_opacity=0,
  41.         ).move_to(self.mobject.get_center())
  42.         # 更新涟漪对象
  43.         ripple.become(new_ripple)
  44.         # 更新发光层
  45.         for j, glow in enumerate(glow_group):
  46.             phase = j / self.glow_num
  47.             # 设置发光层属性
  48.             glow.become(new_ripple.copy())
  49.             glow.set_stroke(
  50.                 width=self.glow_width * (1 - phase) + 1,  # 宽度递减
  51.                 color=ripple_color,
  52.                 opacity=opacity * 0.3 * (1 - phase),  # 透明度递减
  53.             )
复制代码
这个方法实现了几个关键的视觉效果:

  • 荡漾扩散:通过盘算当前半径,使圆环从中央向外扩散
  • 荡漾淡出:利用正弦函数创建天然的淡出效果
  • 脉冲效果:添加额外的正弦颠簸来模拟荡漾的脉冲闪耀
  • 发光效果:为每个荡漾添加多层发光效果,并使它们的宽度和透明度递减
  • 相位偏移:为差别的荡漾设置差别的相位偏移,创造连续的荡漾效果
2. 利用示例

代码提供了三种差别的利用示例,展示了荡漾效果的多样化应用:
2.1. 单颜色荡漾效果

最简单的应用场景,从一个中央点向外扩散单色荡漾:
  1. class RippleEffectExample(Scene):
  2.     """
  3.     涟漪扩散特效示例场景
  4.     """
  5.     def construct(self):
  6.         # 创建一个点作为涟漪的中心
  7.         center_dot = Dot(color=YELLOW)
  8.         self.add(center_dot)
  9.         # 创建涟漪扩散特效
  10.         ripple_effect = RippleEffect(
  11.             center_dot,
  12.             num_ripples=8,
  13.             max_radius=4.0,
  14.             min_radius=0.1,
  15.             ripple_speed=1.5,
  16.             color=BLUE,
  17.             glow_num=5,
  18.             glow_width=8,
  19.             pulse_frequency=3.0,
  20.         )
  21.         # 将所有涟漪和发光层添加到场景中
  22.         for ripple, glow_group in zip(ripple_effect.ripples, ripple_effect.glow_layers):
  23.             self.add(ripple)
  24.             for glow in glow_group:
  25.                 self.add(glow)
  26.         # 播放动画
  27.         self.play(ripple_effect, run_time=5)
  28.         self.wait()
复制代码

2.2. 双荡漾效果

展示两个同时扩散的荡漾效果,可以用于体现两个对象之间的交互:
  1. class DualRippleEffectExample(Scene):
  2.     """
  3.     双涟漪扩散特效示例场景
  4.     展示两个同时扩散的涟漪效果
  5.     """
  6.     def construct(self):
  7.         # 创建两个点作为涟漪的中心
  8.         center_dot1 = Dot(color=YELLOW).shift(LEFT * 2)
  9.         center_dot2 = Dot(color=RED).shift(RIGHT * 2)
  10.         self.add(center_dot1, center_dot2)
  11.         # 创建两个涟漪扩散特效
  12.         ripple_effect1 = RippleEffect(
  13.             center_dot1,
  14.             num_ripples=6,
  15.             max_radius=1.5,
  16.             min_radius=0.1,
  17.             ripple_speed=1.2,
  18.             color=BLUE,
  19.             glow_num=4,
  20.             glow_width=6,
  21.             pulse_frequency=5.5,
  22.         )
  23.         ripple_effect2 = RippleEffect(
  24.             center_dot2,
  25.             num_ripples=6,
  26.             max_radius=1.5,
  27.             min_radius=0.1,
  28.             ripple_speed=1.2,
  29.             color=RED,
  30.             glow_num=8,
  31.             glow_width=4,
  32.             pulse_frequency=2.5,
  33.         )
  34.         # 将所有涟漪和发光层添加到场景中
  35.         for ripple, glow_group in zip(
  36.             ripple_effect1.ripples, ripple_effect1.glow_layers
  37.         ):
  38.             self.add(ripple)
  39.             for glow in glow_group:
  40.                 self.add(glow)
  41.         for ripple, glow_group in zip(
  42.             ripple_effect2.ripples, ripple_effect2.glow_layers
  43.         ):
  44.             self.add(ripple)
  45.             for glow in glow_group:
  46.                 self.add(glow)
  47.         # 同时播放两个动画
  48.         self.play(ripple_effect1, ripple_effect2, run_time=5)
  49.         self.wait()
复制代码

2.3. 多颜色荡漾效果

最具视觉打击力的效果,从一个中央点向外扩散多种颜色的荡漾:
  1. class MultiColorRippleEffectExample(Scene):
  2.     def construct(self):
  3.         # 创建一个点作为涟漪的中心
  4.         center_dot = Dot(color=YELLOW)
  5.         self.add(center_dot)
  6.         # 创建涟漪扩散特效
  7.         ripple_effect = RippleEffect(
  8.             center_dot,
  9.             num_ripples=8,
  10.             max_radius=4.0,
  11.             min_radius=0.1,
  12.             ripple_speed=1.5,
  13.             color=[BLUE, RED, GREEN, YELLOW, ORANGE],
  14.             glow_num=5,
  15.             glow_width=8,
  16.             pulse_frequency=3.0,
  17.         )
  18.         # 将所有涟漪和发光层添加到场景中
  19.         for ripple, glow_group in zip(ripple_effect.ripples, ripple_effect.glow_layers):
  20.             self.add(ripple)
  21.             for glow in glow_group:
  22.                 self.add(glow)
  23.         # 播放动画
  24.         self.play(ripple_effect, run_time=5)
  25.         self.wait()
复制代码

3. 总结

3.1. 殊效特点


  • 高度可定制:提供了丰富的参数控制,包罗荡漾数目、巨细、速率、颜色、发光效果等
  • 视觉效果精美:通过多层发光、脉冲效果和相位偏移,创造出传神而富丽的荡漾效果
  • 支持多颜色模式:可以实现单色荡漾或彩虹般的多色荡漾效果
  • 易于扩展:基于Manim的Animation类,易于与其他动画效果联合
3.2. 利用场景

荡漾扩散殊效在以了局景中特殊有用:

  • 数据可视化:用于突出表现数据点或数据厘革
  • 科学动画:模拟水面波纹、声波、电磁波等物理征象
  • 教诲视频:在表明概念时吸引观众注意力,进步学习效果
  • 产物展示:为产物演示添加视觉亮点,增强吸引力
  • 片头片尾:作为视频过渡或装饰元素
  • 用户界面筹划:在交互式应用中提供视觉反馈
通过本文先容的RippleEffect类,你可以轻松在本身的动画项目中实现这一效果,为你的作品增加视觉吸引力。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表