Manim實現閃電特效
本文將詳細介紹如何使用Manim框架來實現一個逼真的閃電特效。
1. 實現原理
閃電特效通過LightningAnimation類實現,該類繼承自Manim的基礎Animation類,
主要基于以下幾個核心原理:
1.1. 折線生成與隨機偏移
閃電的基本形狀是通過在起點和終點之間創建多個帶有隨機偏移的轉折點來實現的:
# 初始化閃電的轉折點
def initialize_points(self):
# 在起點和終點之間均勻分布轉折點
for i in range(1, self.num_points + 1):
t = i / (self.num_points + 1)
# 基礎位置
self.points[i] = self.start_point + t * self.vector
# 添加隨機偏移
perpendicular = np.array([-self.direction[1], self.direction[0], 0])
offset_strength = self.distance * 0.1
random_offset = np.random.uniform(-offset_strength, offset_strength)
self.points[i] += random_offset * perpendicular
這段代碼首先在起點和終點之間均勻分布轉折點,然后對每個轉折點添加垂直于閃電方向的隨機偏移,從而模擬閃電不規則的鋸齒形狀。
1.2. 分叉閃電系統
為了增強真實感,代碼實現了分叉閃電系統:
# 初始化分叉點
for f in range(self.num_forks):
# 隨機選擇分叉點在主閃電上的位置
fork_start_index = np.random.randint(2, self.num_points - 2)
fork_start_point = self.points[fork_start_index]
# 計算分叉方向
fork_direction = self.direction + np.array(
[np.random.uniform(-0.5, 0.5), np.random.uniform(-0.5, 0.5), 0]
)
fork_direction = fork_direction / np.linalg.norm(fork_direction)
# 計算分叉終點和轉折點
# ...省略部分代碼...
系統會隨機選擇主閃電上的點作為分叉起點,然后生成帶有隨機方向和長度的分叉閃電。每個分叉也有自己的隨機轉折點,使其看起來更加自然。
1.3. 動態變化效果
閃電效果的動態變化主要通過interpolate_mobject方法實現,該方法在動畫過程中不斷更新閃電的形狀、顏色和透明度:
def interpolate_mobject(self, alpha):
# 計算時間參數,使用正弦波來創造閃爍效果
time = self.speed * alpha
# 動態調整轉折點位置
# ...省略部分代碼...
# 動態調整透明度,創造閃爍效果
alpha_value = self.alpha_range[0] + (
self.alpha_range[1] - self.alpha_range[0]
) * (0.5 + 0.5 * np.sin(time * 20))
self.lightning_line.set_stroke(opacity=alpha_value)
# 動態調整粗細
thickness = self.thickness_range[0] + (
self.thickness_range[1] - self.thickness_range[0]
) * (0.5 + 0.5 * np.sin(time * 15))
self.lightning_line.set_stroke(width=thickness)
# ...省略部分代碼...
代碼使用正弦函數創造閃電的閃爍和粗細變化效果,結合隨機因素使每次播放的閃電效果都略有不同,增強了視覺真實感。
1.4. LightningAnimation 類的參數
LightningAnimation 類提供了豐富的參數選項,可以靈活調整閃電效果的各種特性。
class LightningAnimation(Animation):
"""
閃電特效動畫類
通過創建多個帶有尖銳轉折的折線,并動態調整折線的形狀、顏色和透明度來模擬閃電的效果
包含主閃電和分叉閃電效果
"""
def __init__(
self,
start_point,
end_point,
num_points=10,
thickness_range=(0.1, 0.5),
color=YELLOW,
alpha_range=(0.5, 1),
speed=1,
num_forks=3,
fork_probability=0.3,
**kwargs
):
"""
初始化閃電動畫
參數:
- start_point: 閃電起點坐標
- end_point: 閃電終點坐標
- num_points: 閃電中的轉折點數量
- thickness_range: 閃電粗細范圍 (最小值, 最大值)
- color: 閃電顏色
- alpha_range: 透明度范圍 (最小值, 最大值)
- speed: 動畫速度
- num_forks: 分叉閃電的數量
- fork_probability: 分叉閃電出現的概率
"""
pass # 省略... ...
參數主要含義:
- 位置參數:
start_point: 閃電的起點坐標,使用 NumPy 數組表示 (x, y, z)end_point: 閃電的終點坐標,同樣使用 NumPy 數組表示 (x, y, z)
- 形狀與復雜度參數:
num_points: 閃電中的轉折點數量,默認為 10- 數值越大,閃電的路徑越復雜,鋸齒狀越明顯
- 數值越小,閃電越接近直線
num_forks: 分叉閃電的數量,默認為 3- 決定了閃電會產生多少個分支
fork_probability: 分叉閃電出現的概率,默認為 0.3- 控制每次動畫播放時,實際顯示的分叉數量
- 值為 0 時不會顯示分叉,值為 1 時所有分叉都會顯示
- 視覺效果參數:
thickness_range: 閃電粗細范圍,格式為 (最小值, 最大值),默認為 (0.1, 0.5)- 控制閃電的最大和最小寬度
- 閃電在動畫過程中會在此范圍內動態變化
color: 閃電顏色,默認為 YELLOW- 可以使用 Manim 提供的顏色常量,如 YELLOW、WHITE、BLUE 等
alpha_range: 透明度范圍,格式為 (最小值, 最大值),默認為 (0.5, 1)- 控制閃電的透明度變化范圍
- 值越小,閃電越透明
- 動畫參數:
speed: 動畫速度,默認為 1- 控制閃電閃爍和動態變化的速率
- 數值越大,閃電變化越快
2. 使用示例
LightningAnimation類提供了豐富的參數,可以靈活調整閃電效果。下面是幾個不同場景的使用示例:
2.1. 示例1:黃色對角閃電
class Example01(Scene):
def construct(self):
# 設置背景色為深色,以突出閃電效果
self.camera.background_color = "#0d0d1a" # 深藍色背景
# 創建閃電:從左上角到右下角,帶分叉效果
start_point = np.array([-5, 3, 0])
end_point = np.array([5, -3, 0])
lightning = LightningAnimation(
start_point,
end_point,
num_points=15, # 轉折點數量
color=YELLOW, # 閃電顏色
thickness_range=(0.15, 0.6), # 粗細范圍
speed=2, # 動畫速度
num_forks=5, # 分叉數量
fork_probability=0.4 # 分叉出現概率
)
# 播放閃電動畫
self.play(lightning, run_time=2)
self.wait()

2.2. 示例2:白色對角閃電
class Example02(Scene):
def construct(self):
self.camera.background_color = "#0d0d1a"
# 創建閃電:從右上角到左下角
start_point = np.array([5, 3, 0])
end_point = np.array([-5, -3, 0])
lightning = LightningAnimation(
start_point,
end_point,
num_points=12,
color=WHITE,
thickness_range=(0.25, 0.7),
speed=1.5,
num_forks=4,
fork_probability=0.3,
)
self.play(lightning, run_time=2)
self.wait()

2.3. 示例3:藍色垂直閃電
class Example03(Scene):
def construct(self):
self.camera.background_color = "#0d0d1a"
# 創建閃電:較短的垂直閃電
start_point = np.array([0, 4, 0])
end_point = np.array([0, 0, 0])
lightning = LightningAnimation(
start_point,
end_point,
num_points=8,
color=BLUE,
alpha_range=(0.7, 1),
thickness_range=(0.1, 0.4),
speed=3,
num_forks=3,
fork_probability=0.5,
)
self.play(lightning, run_time=1.5)
self.wait()

這些示例展示了如何通過調整參數來創建不同形狀、顏色和特性的閃電效果,以適應不同的場景需求。
3. 總結
3.1. 特效特點
- 高度可定制:通過調整參數可以創建各種不同類型的閃電效果
- 真實感強:結合隨機因素和動態變化,模擬真實閃電的不規則性和閃爍效果
- 層次豐富:主閃電和分叉閃電系統共同作用,創造出復雜而自然的閃電效果
- 易于集成:作為Manim的Animation子類,可以方便地與其他Manim動畫元素結合使用
3.2. 使用場景
- 天氣現象模擬:在氣象相關的可視化中展示雷電現象
- 科幻與奇幻場景:為魔法效果、能量釋放或科幻場景增添視覺沖擊力
- 強調與過渡:作為場景轉換或重點內容強調的動態效果
- 教育演示:在物理課程中演示電場放電等相關概念
- 藝術創作:用于抽象動畫和視覺藝術作品
通過這個LightningAnimation類,我們可以在Manim項目中輕松實現逼真的閃電特效,為動畫作品增添生動的視覺元素。

浙公網安備 33010602011771號