Manim实现脉冲闪烁特效

在数学可视化中,脉冲闪烁特效能像聚光灯一样引导观众注意力,突出关键公式、特殊点或重要结论。

本文将介绍如何一步步通过代码来实现这个特效,并通过参数精准控制视觉效果。

1. 实现原理

脉冲闪烁特效的核心是周期性改变发光体的半径和透明度,模拟能量波动的视觉效果。

这个特效实现的关键思路如下:

  1. 创建一个发光圆环:作为产生脉冲闪烁效果的基础。
  2. 动态更新圆环的半径和透明度:通过正弦函数模拟周期性的脉冲效果,使得圆环在扩张和收缩的过程中产生闪烁的感觉。
  3. 参数化设计:通过提供多个参数,使得特效可以灵活应用于各种场景,满足不同的需求。

完整的特效代码如下:

python 复制代码
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 − 4 a c b^2-4ac b2−4ac,再高亮 2 a 2a 2a。

python 复制代码
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个不同位置的点。

python 复制代码
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,创建层次丰富的视觉引导效果。

相关推荐
红尘散仙13 分钟前
我把终端小说阅读器接上了 AI Agent:TRNovel 现在能用 skill 生成书源了
人工智能·后端·rust
心中有国也有家21 分钟前
GE图引擎深度解析——CANN的计算图优化与执行引擎
人工智能·pytorch·python·学习·numpy
卷毛的技术笔记2 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
编程大师哥2 小时前
匿名函数 lambda + 高阶函数
java·python·算法
vb2008112 小时前
FastAPI APIRouter
开发语言·python
会编程的土豆2 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
adrninistrat0r2 小时前
Java调用链MCP分析工具
java·python·ai编程
喵个咪2 小时前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm
杨充2 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
basketball6163 小时前
Go 语言从入门到进阶:4. 数组和MAP使用方法总结
开发语言·后端·golang