河北矩星源车灯 發表於 2025-9-17 23:45:00

Manim实现脉冲闪烁特效

<p>在数学可视化中,<strong>脉冲闪烁</strong>特效能像聚光灯一样引导观众注意力,突出关键公式、特殊点或重要结论。</p>
<p>本文将介绍如何一步步通过代码来实现这个特效,并通过参数精准控制视觉效果。</p>
<h1 id="1-实现原理">1. 实现原理</h1>
<p><strong>脉冲闪烁特效</strong>的核心是周期性改变发光体的半径和透明度,模拟能量波动的视觉效果。</p>
<p>这个特效实现的关键思路如下:</p>
<ol>
<li><strong>创建一个发光圆环</strong>:作为产生脉冲闪烁效果的基础。</li>
<li><strong>动态更新圆环的半径和透明度</strong>:通过正弦函数模拟周期性的脉冲效果,使得圆环在扩张和收缩的过程中产生闪烁的感觉。</li>
<li><strong>参数化设计</strong>:通过提供多个参数,使得特效可以灵活应用于各种场景,满足不同的需求。</li>
</ol>
<p>完整的特效代码如下:</p>
<pre><code class="language-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)

      # 半径在间波动
      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)
</code></pre>
<p>代码中已经添加了详细的注释。</p>
<h1 id="2-使用示例">2. 使用示例</h1>
<p>下面从示例来看看如何使用我们自己定制的<strong>脉冲闪烁</strong>特效。</p>
<h2 id="21-高亮公式某个部分">2.1. 高亮公式某个部分</h2>
<p>这个示例使用<strong>脉冲闪烁</strong>特效高亮公式的某个部分,先高亮$ b^2-4ac <span class="math inline">\(,再高亮\)</span> 2a $。</p>
<pre><code class="language-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# 选中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# 选中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()
</code></pre>
<p><img src="https://img2024.cnblogs.com/blog/83005/202509/83005-20250917234450588-1028729456.gif" alt="" loading="lazy"></p>
<h2 id="22-标记函数中指定点">2.2. 标记函数中指定点</h2>
<p>这个示例中,使用<strong>脉冲闪烁</strong>特效依次高亮函数曲线上的3个不同位置的点。</p>
<pre><code class="language-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()
</code></pre>
<p><img src="https://img2024.cnblogs.com/blog/83005/202509/83005-20250917234450600-415480575.gif" alt="" loading="lazy"></p>
<h1 id="3-总结">3. 总结</h1>
<p><strong>脉冲闪烁</strong>特效如同数学动画中的"荧光笔",能精确引导观众视线到关键元素。</p>
<p>通过<code>Manim</code>灵活的代码控制,我们不仅能实现基础脉冲效果,还能结合具体数学内容调整动态特性。</p>
<p>这个特效特别适用于:</p>
<ul>
<li>定理证明中的关键步骤</li>
<li>公式中的核心变量</li>
<li>几何图形的特殊点</li>
<li>算法演示的关键节点</li>
</ul>
<p>在复杂场景中,可同时启动多个不同参数的<code>PulseFlashEffect</code>,创建层次丰富的视觉引导效果。</p><br><br>
来源:https://www.cnblogs.com/wang_yb/p/19097898
頁: [1]
查看完整版本: Manim实现脉冲闪烁特效