Manim实现旋转扭曲特效
<p>在数学动画制作中,特殊效果可以极大地增强视觉表现力和吸引力。</p><p>本文将介绍如何使用<code>Manim</code>框架实现一个<strong>旋转扭曲</strong>特效,通过自定义动画类来创建独特的视觉效果。</p>
<h1 id="实现原理">实现原理</h1>
<p><strong>旋转扭曲</strong>特效的核心是<strong>通过修改对象上每个点的坐标</strong>来实现扭曲效果。</p>
<p>在<code>Manim</code>中,我们可以通过继承<code>Animation</code>类并重写<code>interpolate_mobject</code>方法来创建自定义动画。</p>
<h2 id="自定义动画类的结构">自定义动画类的结构</h2>
<pre><code class="language-python">class TwistAnimation(Animation):
def __init__(
self,
mobject,
center=ORIGIN,
twist_angle=TAU,
strength=1.0,
direction="clockwise",
**kwargs
):
super().__init__(mobject, **kwargs)
# 存储初始状态以便在动画过程中重置
self.center = center
self.twist_angle = twist_angle
self.strength = strength
self.direction = direction
# 根据方向调整扭曲角度
if direction == "counterclockwise":
self.twist_angle = -self.twist_angle
</code></pre>
<p>这个类定义了几个关键参数:</p>
<ul>
<li><code>mobject</code>:要进行扭曲的Manim对象</li>
<li><code>center</code>:扭曲中心点,默认为原点</li>
<li><code>twist_angle</code>:总扭曲角度,默认为TAU(360度)</li>
<li><code>strength</code>:扭曲强度,默认为1.0</li>
<li><code>direction</code>:扭曲方向,可以是"clockwise"(顺时针)或"counterclockwise"(逆时针)</li>
</ul>
<h2 id="扭曲算法的核心实现">扭曲算法的核心实现</h2>
<p>扭曲效果的核心在于<code>interpolate_mobject</code>方法,它在动画的每一帧被调用,根据当前的进度<code>alpha</code>更新对象的形状:</p>
<pre><code class="language-python">def interpolate_mobject(self, alpha):
# 重置对象到初始状态
self.mobject.become(self.starting_mobject)
# 计算当前的扭曲角度
current_twist_angle = alpha * self.twist_angle
# 获取对象的所有点
points = self.mobject.points
# 对每个点应用扭曲变换
for i in range(len(points)):
# 计算点相对于中心的位置
point = points
rel_point = point - self.center
# 计算点到中心的距离
distance = np.linalg.norm(rel_point)
# 如果点在中心,则不进行变换
if distance == 0:
continue
# 计算点的极角
angle = np.arctan2(rel_point, rel_point)
# 计算扭曲后的角度:距离中心越远,扭曲角度越大
twisted_angle = angle + current_twist_angle * (distance * self.strength)
# 计算扭曲后的坐标
twisted_x = self.center + distance * np.cos(twisted_angle)
twisted_y = self.center + distance * np.sin(twisted_angle)
# 更新点的位置
points = np.array(])
# 将更新后的点应用到对象上
self.mobject.set_points(points)
</code></pre>
<p>这个算法的<strong>核心思想</strong>是:</p>
<ol>
<li>将对象上的每个点转换为相对于扭曲中心的极坐标</li>
<li>根据点到中心的距离计算扭曲角度(距离越远,扭曲越大)</li>
<li>将扭曲后的极坐标转换回笛卡尔坐标</li>
<li>更新对象上所有点的位置</li>
</ol>
<p>这种实现方式使得扭曲效果非常自然,尤其是对于几何形状对象。</p>
<h1 id="使用示例">使用示例</h1>
<p>代码中提供了三个示例场景,展示了如何使用这个扭曲特效。</p>
<h2 id="基本扭曲效果">基本扭曲效果</h2>
<p><code>Example01</code>类展示了基本的扭曲效果,包括顺时针和逆时针扭曲:</p>
<pre><code class="language-python">class Example01(Scene):
"""基本的扭曲效果"""
def construct(self):
# 创建一个矩形作为扭曲对象
rect = Rectangle(width=4, height=2, color=BLUE, fill_opacity=0.5)
# 添加扭曲动画
self.play(Create(rect))
self.wait()
self.play(TwistAnimation(rect, run_time=2))
self.play(TwistAnimation(rect, twist_angle=-TAU, run_time=2))# 反向扭曲
self.wait()
</code></pre>
<p>这个示例创建了一个蓝色矩形,然后先应用顺时针扭曲,再应用逆时针扭曲。</p>
<p><img src="https://img2024.cnblogs.com/blog/83005/202510/83005-20251007093803884-1342167556.gif" alt="" loading="lazy"></p>
<h2 id="不同扭曲中心的效果">不同扭曲中心的效果</h2>
<p><code>Example02</code>类展示了使用不同扭曲中心的效果:</p>
<pre><code class="language-python">class Example02(Scene):
"""不同扭曲中心的效果"""
def construct(self):
# 创建多个对象,并设置不同的扭曲中心
circle1 = Circle(radius=0.8, color=RED, fill_opacity=0.5)
circle1.shift(LEFT * 2)
circle2 = Circle(radius=0.8, color=GREEN, fill_opacity=0.5)
circle3 = Circle(radius=0.8, color=BLUE, fill_opacity=0.5)
circle3.shift(RIGHT * 2)
# 添加中心标记
center_marker1 = Dot(color=WHITE).shift(LEFT * 3)
center_marker3 = Dot(color=WHITE).shift(RIGHT * 3)
# 添加对象到场景
self.play(Create(circle1), Create(circle2), Create(circle3))
self.play(Create(center_marker1), Create(center_marker3))
self.wait()
# 应用扭曲动画,使用不同的中心
self.play(
TwistAnimation(circle1, center=center_marker1.get_center(), run_time=2),
TwistAnimation(circle2, center=ORIGIN, run_time=2),
TwistAnimation(circle3, center=center_marker3.get_center(), run_time=2),
)
self.wait()
</code></pre>
<p>这个示例创建了<strong>三个</strong>不同颜色的圆,并分别使用不同的中心点进行扭曲,直观地展示了扭曲中心对效果的影响。</p>
<p><img src="https://img2024.cnblogs.com/blog/83005/202510/83005-20251007093803868-235302615.gif" alt="" loading="lazy"></p>
<h2 id="不同扭曲强度的效果">不同扭曲强度的效果</h2>
<p><code>Example03</code>类展示了使用不同扭曲强度的效果:</p>
<pre><code class="language-python">class Example03(Scene):
"""演示不同扭曲强度的效果"""
def construct(self):
# 创建多个对象,并设置不同的扭曲强度
square1 = Square(side_length=1.5, color=YELLOW, fill_opacity=0.5)
square1.shift(LEFT * 2)
square2 = Square(side_length=1.5, color=MAROON, fill_opacity=0.5)
square3 = Square(side_length=1.5, color=TEAL, fill_opacity=0.5)
square3.shift(RIGHT * 2)
# 添加对象到场景
self.play(Create(square1), Create(square2), Create(square3))
self.wait()
# 应用扭曲动画,使用不同的强度
self.play(
TwistAnimation(square1, strength=0.5, run_time=2),
TwistAnimation(square2, strength=1.0, run_time=2),
TwistAnimation(square3, strength=2.0, run_time=2),
)
self.wait()
</code></pre>
<p>这个示例创建了<strong>三个</strong>不同颜色的正方形,并分别应用不同强度的扭曲,展示了扭曲强度对效果的影响。</p>
<p><img src="https://img2024.cnblogs.com/blog/83005/202510/83005-20251007093803903-689122922.gif" alt="" loading="lazy"></p>
<h1 id="总结">总结</h1>
<h2 id="特效特点">特效特点</h2>
<p>这个旋转扭曲特效具有以下特点:</p>
<ol>
<li><strong>高度可定制性</strong>:通过调整扭曲中心、扭曲角度、扭曲强度和扭曲方向,可以创建各种不同的扭曲效果</li>
<li><strong>自然流畅</strong>:基于极坐标变换的算法使得扭曲效果非常自然流畅</li>
<li><strong>适用范围广</strong>:可以应用于各种<code>Manim</code>对象,包括几何形状和文本</li>
<li><strong>易于集成</strong>:作为一个自定义<code>Animation</code>类,可以很容易地集成到现有<code>Manim</code>项目中</li>
</ol>
<h2 id="使用场景">使用场景</h2>
<p>这个扭曲特效可以用于以下场景:</p>
<ol>
<li><strong>数学教学</strong>:用于展示几何变换、极坐标转换等数学概念</li>
<li><strong>视觉效果增强</strong>:为动画添加独特的视觉效果,增强观众的注意力</li>
<li><strong>转场动画</strong>:作为场景之间的转场效果</li>
<li><strong>强调重点</strong>:通过扭曲效果突出显示重要的对象或概念</li>
<li><strong>创意动画</strong>:用于创建具有艺术感的动画效果</li>
</ol>
<p>通过这个简单而强大的特效,我们可以为<code>Manim</code>动画增添更多的视觉表现力和创意可能性。</p><br><br>
来源:https://www.cnblogs.com/wang_yb/p/19128210
頁:
[1]