在数学可视化中,脉冲闪烁特效能像聚光灯一样引导观众注意力,突出关键公式、特殊点或重要结论。
本文将介绍如何一步步通过代码来实现这个特效,并通过参数精准控制视觉效果。
1. 实现原理
脉冲闪烁特效的核心是周期性改变发光体的半径和透明度,模拟能量波动的视觉效果。
这个特效实现的关键思路如下:
- 创建一个发光圆环:作为产生脉冲闪烁效果的基础。
- 动态更新圆环的半径和透明度:通过正弦函数模拟周期性的脉冲效果,使得圆环在扩张和收缩的过程中产生闪烁的感觉。
- 参数化设计:通过提供多个参数,使得特效可以灵活应用于各种场景,满足不同的需求。
完整的特效代码如下:
from manim import * class PulseFlashEffect(Animation): def __init__( self, mobject: Mobject, color: str = YELLOW, max_radius: float = 2.0, min_radius: float = 0.1, pulse_speed: float = 1.0, glow_width: float = 10, **kwargs ): """ 构造函数。 Parameters: mobject - 这是要添加脉冲闪烁效果的对象,必须是一个Mobject类型的对象 color - 发光的颜色,默认为黄色(YELLOW) max_radius - 发光圆环的最大半径,默认为 2.0 min_radius - 发光圆环的最小半径,默认为 0.1 pulse_speed - 脉冲的速度,默认为 1.0。这个参数控制脉冲的频率 glow_width - 发光圆环的宽度,默认为 10 **kwargs - 用于传递额外的关键字参数到父类Animation的构造函数中 """ # 创建发光圆环,并将发光的中心移动到mobject的中心位置 self.glow = Circle( radius=min_radius, stroke_width=glow_width, stroke_color=color, fill_opacity=0, stroke_opacity=0.5, ).move_to(mobject.get_center()) # 参数设置 self.max_radius = max_radius self.min_radius = min_radius self.pulse_speed = pulse_speed super().__init__(self.glow, **kwargs) def interpolate_mobject(self, alpha: float): """ 实现动画效果的核心方法。 Parameters: alpha - 是一个介于 0 和 1 之间的参数,表示动画的进度 """ # 正弦波动控制半径和透明度 t = self.pulse_speed * self.run_time * alpha phase = np.sin(2 * PI * t) # 半径在[min_radius, max_radius]间波动 radius = interpolate(self.min_radius, self.max_radius, 0.5 * (phase + 1)) # 透明度随半径增大而衰减 opacity = interpolate( 0.8, 0.1, (radius - self.min_radius) / (self.max_radius - self.min_radius) ) # 更新发光圆环的透明度和宽度 self.glow.set_stroke(opacity=opacity) self.glow.set_width(2 * radius)
代码中已经添加了详细的注释。
2. 使用示例
下面从示例来看看如何使用我们自己定制的脉冲闪烁特效。
2.1. 高亮公式某个部分
这个示例使用脉冲闪烁特效高亮公式的某个部分,先高亮$ b^2-4ac (,再高亮) 2a $。
class PulseFlashEffectExample01(Scene): def construct(self): # 创建二次方程求根公式 formula = MathTex( r"x = frac{-b pm sqrt{b^2 - 4ac}}{2a}", font_size=48, ) self.add(formula) # 在判别式部分添加脉冲特效 discriminant = formula[0][7:13] # 选中b²-4ac discriminant.set_color(RED) glow = PulseFlashEffect( discriminant, color=RED, max_radius=1, pulse_speed=2.0, remover=True, ) self.play( discriminant.animate.set_color(RED), glow, run_time=2, ) # 启动脉冲 discriminant.set_color(WHITE) discriminant = formula[0][14:] # 选中2a glow = PulseFlashEffect( discriminant, color=BLUE, max_radius=1, pulse_speed=2.0, remover=True, ) self.play( discriminant.animate.set_color(BLUE), glow, run_time=2, ) # 启动脉冲 self.wait()

2.2. 标记函数中指定点
这个示例中,使用脉冲闪烁特效依次高亮函数曲线上的3个不同位置的点。
class PulseFlashEffectExample02(Scene): def construct(self): # 绘制函数图像 axes = Axes(x_range=[-3, 3], y_range=[-1, 10]) graph = axes.plot(lambda x: x**2, color=BLUE) self.add(axes, graph) # 标记顶点(0,0) dot1 = Dot(color=YELLOW).move_to(axes.c2p(0, 0)) dot2 = Dot(color=BLUE).move_to(axes.c2p(1, 1)) dot3 = Dot(color=RED).move_to(axes.c2p(2, 4)) # 设置每个点的快速脉冲 pulse1 = PulseFlashEffect( dot1, color=YELLOW, max_radius=0.8, min_radius=0.2, pulse_speed=3.0, remover=True, ) pulse2 = PulseFlashEffect( dot2, color=BLUE, max_radius=0.8, min_radius=0.2, pulse_speed=3.0, remover=True, ) pulse3 = PulseFlashEffect( dot3, color=RED, max_radius=0.8, min_radius=0.2, pulse_speed=3.0, remover=True, ) self.play(FadeIn(dot1), pulse1) self.play(FadeIn(dot2), pulse2) self.play(FadeIn(dot3), pulse3) self.wait()

3. 总结
脉冲闪烁特效如同数学动画中的"荧光笔",能精确引导观众视线到关键元素。
通过Manim灵活的代码控制,我们不仅能实现基础脉冲效果,还能结合具体数学内容调整动态特性。
这个特效特别适用于:
- 定理证明中的关键步骤
- 公式中的核心变量
- 几何图形的特殊点
- 算法演示的关键节点
在复杂场景中,可同时启动多个不同参数的PulseFlashEffect,创建层次丰富的视觉引导效果。