找回密码
 立即注册
首页 业界区 业界 Manim实现脉冲闪烁特效

Manim实现脉冲闪烁特效

膏包 2025-10-1 17:50:54
在数学可视化中,脉冲闪烁特效能像聚光灯一样引导观众注意力,突出关键公式、特殊点或重要结论。
本文将介绍如何一步步通过代码来实现这个特效,并通过参数精准控制视觉效果。
1. 实现原理

脉冲闪烁特效的核心是周期性改变发光体的半径和透明度,模拟能量波动的视觉效果。
这个特效实现的关键思路如下:

  • 创建一个发光圆环:作为产生脉冲闪烁效果的基础。
  • 动态更新圆环的半径和透明度:通过正弦函数模拟周期性的脉冲效果,使得圆环在扩张和收缩的过程中产生闪烁的感觉。
  • 参数化设计:通过提供多个参数,使得特效可以灵活应用于各种场景,满足不同的需求。
完整的特效代码如下:
  1. from manim import *
  2. class PulseFlashEffect(Animation):
  3.     def __init__(
  4.         self,
  5.         mobject: Mobject,
  6.         color: str = YELLOW,
  7.         max_radius: float = 2.0,
  8.         min_radius: float = 0.1,
  9.         pulse_speed: float = 1.0,
  10.         glow_width: float = 10,
  11.         **kwargs
  12.     ):
  13.         """
  14.         构造函数。
  15.         Parameters:
  16.             mobject - 这是要添加脉冲闪烁效果的对象,必须是一个Mobject类型的对象
  17.             color - 发光的颜色,默认为黄色(YELLOW)
  18.             max_radius - 发光圆环的最大半径,默认为 2.0
  19.             min_radius - 发光圆环的最小半径,默认为 0.1
  20.             pulse_speed - 脉冲的速度,默认为 1.0。这个参数控制脉冲的频率
  21.             glow_width - 发光圆环的宽度,默认为 10
  22.             **kwargs - 用于传递额外的关键字参数到父类Animation的构造函数中
  23.         """
  24.         # 创建发光圆环,并将发光的中心移动到mobject的中心位置
  25.         self.glow = Circle(
  26.             radius=min_radius,
  27.             stroke_width=glow_width,
  28.             stroke_color=color,
  29.             fill_opacity=0,
  30.             stroke_opacity=0.5,
  31.         ).move_to(mobject.get_center())
  32.         # 参数设置
  33.         self.max_radius = max_radius
  34.         self.min_radius = min_radius
  35.         self.pulse_speed = pulse_speed
  36.         super().__init__(self.glow, **kwargs)
  37.     def interpolate_mobject(self, alpha: float):
  38.         """
  39.         实现动画效果的核心方法。
  40.         Parameters:
  41.             alpha - 是一个介于 0 和 1 之间的参数,表示动画的进度
  42.         """
  43.         # 正弦波动控制半径和透明度
  44.         t = self.pulse_speed * self.run_time * alpha
  45.         phase = np.sin(2 * PI * t)
  46.         # 半径在[min_radius, max_radius]间波动
  47.         radius = interpolate(self.min_radius, self.max_radius, 0.5 * (phase + 1))
  48.         # 透明度随半径增大而衰减
  49.         opacity = interpolate(
  50.             0.8, 0.1, (radius - self.min_radius) / (self.max_radius - self.min_radius)
  51.         )
  52.         # 更新发光圆环的透明度和宽度
  53.         self.glow.set_stroke(opacity=opacity)
  54.         self.glow.set_width(2 * radius)
复制代码
代码中已经添加了详细的注释。
2. 使用示例

下面从示例来看看如何使用我们自己定制的脉冲闪烁特效。
2.1. 高亮公式某个部分

这个示例使用脉冲闪烁特效高亮公式的某个部分,先高亮$ b^2-4ac \(,再高亮\) 2a $。
  1. class PulseFlashEffectExample01(Scene):
  2.     def construct(self):
  3.         # 创建二次方程求根公式
  4.         formula = MathTex(
  5.             r"x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}",
  6.             font_size=48,
  7.         )
  8.         self.add(formula)
  9.         # 在判别式部分添加脉冲特效
  10.         discriminant = formula[0][7:13]  # 选中b²-4ac
  11.         discriminant.set_color(RED)
  12.         glow = PulseFlashEffect(
  13.             discriminant,
  14.             color=RED,
  15.             max_radius=1,
  16.             pulse_speed=2.0,
  17.             remover=True,
  18.         )
  19.         self.play(
  20.             discriminant.animate.set_color(RED),
  21.             glow,
  22.             run_time=2,
  23.         )  # 启动脉冲
  24.         discriminant.set_color(WHITE)
  25.         discriminant = formula[0][14:]  # 选中2a
  26.         glow = PulseFlashEffect(
  27.             discriminant,
  28.             color=BLUE,
  29.             max_radius=1,
  30.             pulse_speed=2.0,
  31.             remover=True,
  32.         )
  33.         self.play(
  34.             discriminant.animate.set_color(BLUE),
  35.             glow,
  36.             run_time=2,
  37.         )  # 启动脉冲
  38.         self.wait()
复制代码
1.gif

2.2. 标记函数中指定点

这个示例中,使用脉冲闪烁特效依次高亮函数曲线上的3个不同位置的点。
  1. class PulseFlashEffectExample02(Scene):
  2.     def construct(self):
  3.         # 绘制函数图像
  4.         axes = Axes(x_range=[-3, 3], y_range=[-1, 10])
  5.         graph = axes.plot(lambda x: x**2, color=BLUE)
  6.         self.add(axes, graph)
  7.         # 标记顶点(0,0)
  8.         dot1 = Dot(color=YELLOW).move_to(axes.c2p(0, 0))
  9.         dot2 = Dot(color=BLUE).move_to(axes.c2p(1, 1))
  10.         dot3 = Dot(color=RED).move_to(axes.c2p(2, 4))
  11.         # 设置每个点的快速脉冲
  12.         pulse1 = PulseFlashEffect(
  13.             dot1,
  14.             color=YELLOW,
  15.             max_radius=0.8,
  16.             min_radius=0.2,
  17.             pulse_speed=3.0,
  18.             remover=True,
  19.         )
  20.         pulse2 = PulseFlashEffect(
  21.             dot2,
  22.             color=BLUE,
  23.             max_radius=0.8,
  24.             min_radius=0.2,
  25.             pulse_speed=3.0,
  26.             remover=True,
  27.         )
  28.         pulse3 = PulseFlashEffect(
  29.             dot3,
  30.             color=RED,
  31.             max_radius=0.8,
  32.             min_radius=0.2,
  33.             pulse_speed=3.0,
  34.             remover=True,
  35.         )
  36.         self.play(FadeIn(dot1), pulse1)
  37.         self.play(FadeIn(dot2), pulse2)
  38.         self.play(FadeIn(dot3), pulse3)
  39.         self.wait()
复制代码
2.gif

3. 总结

脉冲闪烁特效如同数学动画中的"荧光笔",能精确引导观众视线到关键元素。
通过Manim灵活的代码控制,我们不仅能实现基础脉冲效果,还能结合具体数学内容调整动态特性。
这个特效特别适用于:

  • 定理证明中的关键步骤
  • 公式中的核心变量
  • 几何图形的特殊点
  • 算法演示的关键节点
在复杂场景中,可同时启动多个不同参数的PulseFlashEffect,创建层次丰富的视觉引导效果。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册