Manim實現旋轉扭曲特效
在數學動畫制作中,特殊效果可以極大地增強視覺表現力和吸引力。
本文將介紹如何使用Manim框架實現一個旋轉扭曲特效,通過自定義動畫類來創建獨特的視覺效果。
實現原理
旋轉扭曲特效的核心是通過修改對象上每個點的坐標來實現扭曲效果。
在Manim中,我們可以通過繼承Animation類并重寫interpolate_mobject方法來創建自定義動畫。
自定義動畫類的結構
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
這個類定義了幾個關鍵參數:
mobject:要進行扭曲的Manim對象center:扭曲中心點,默認為原點twist_angle:總扭曲角度,默認為TAU(360度)strength:扭曲強度,默認為1.0direction:扭曲方向,可以是"clockwise"(順時針)或"counterclockwise"(逆時針)
扭曲算法的核心實現
扭曲效果的核心在于interpolate_mobject方法,它在動畫的每一幀被調用,根據當前的進度alpha更新對象的形狀:
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[i]
rel_point = point - self.center
# 計算點到中心的距離
distance = np.linalg.norm(rel_point)
# 如果點在中心,則不進行變換
if distance == 0:
continue
# 計算點的極角
angle = np.arctan2(rel_point[1], rel_point[0])
# 計算扭曲后的角度:距離中心越遠,扭曲角度越大
twisted_angle = angle + current_twist_angle * (distance * self.strength)
# 計算扭曲后的坐標
twisted_x = self.center[0] + distance * np.cos(twisted_angle)
twisted_y = self.center[1] + distance * np.sin(twisted_angle)
# 更新點的位置
points[i] = np.array([twisted_x, twisted_y, point[2]])
# 將更新后的點應用到對象上
self.mobject.set_points(points)
這個算法的核心思想是:
- 將對象上的每個點轉換為相對于扭曲中心的極坐標
- 根據點到中心的距離計算扭曲角度(距離越遠,扭曲越大)
- 將扭曲后的極坐標轉換回笛卡爾坐標
- 更新對象上所有點的位置
這種實現方式使得扭曲效果非常自然,尤其是對于幾何形狀對象。
使用示例
代碼中提供了三個示例場景,展示了如何使用這個扭曲特效。
基本扭曲效果
Example01類展示了基本的扭曲效果,包括順時針和逆時針扭曲:
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()
這個示例創建了一個藍色矩形,然后先應用順時針扭曲,再應用逆時針扭曲。

不同扭曲中心的效果
Example02類展示了使用不同扭曲中心的效果:
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()
這個示例創建了三個不同顏色的圓,并分別使用不同的中心點進行扭曲,直觀地展示了扭曲中心對效果的影響。

不同扭曲強度的效果
Example03類展示了使用不同扭曲強度的效果:
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()
這個示例創建了三個不同顏色的正方形,并分別應用不同強度的扭曲,展示了扭曲強度對效果的影響。

總結
特效特點
這個旋轉扭曲特效具有以下特點:
- 高度可定制性:通過調整扭曲中心、扭曲角度、扭曲強度和扭曲方向,可以創建各種不同的扭曲效果
- 自然流暢:基于極坐標變換的算法使得扭曲效果非常自然流暢
- 適用范圍廣:可以應用于各種
Manim對象,包括幾何形狀和文本 - 易于集成:作為一個自定義
Animation類,可以很容易地集成到現有Manim項目中
使用場景
這個扭曲特效可以用于以下場景:
- 數學教學:用于展示幾何變換、極坐標轉換等數學概念
- 視覺效果增強:為動畫添加獨特的視覺效果,增強觀眾的注意力
- 轉場動畫:作為場景之間的轉場效果
- 強調重點:通過扭曲效果突出顯示重要的對象或概念
- 創意動畫:用于創建具有藝術感的動畫效果
通過這個簡單而強大的特效,我們可以為Manim動畫增添更多的視覺表現力和創意可能性。

浙公網安備 33010602011771號