news 2026/4/17 21:14:42

Manim实现闪电特效

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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项目中轻松实现逼真的闪电特效,为动画作品增添生动的视觉元素。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 23:34:35

Flutter 跨平台开发深度指南:从入门到原理全解析

一、引言 随着移动应用开发需求的增加,跨平台开发框架逐渐成为开发者的首选。Flutter 作为 Google 推出的跨平台开发框架,凭借其出色的性能和开发体验,吸引了大量开发者的关注。对于有一定 JavaScript 或前端开发经验的开发者来说&#xff0c…

作者头像 李华
网站建设 2026/4/18 5:43:53

硬盘突然坏掉,我花了半个月才把数据救回来…(附数据恢复工具)

为平时很多工作资料都在这块盘里,数据恢复的过程持续了小半个月,堪称一场心理和体力的双重折磨。好在最后,大部分文件都救回来了。虽然过程非常花时间,但至少没有全军覆没。🤣这次经历也算是给我自己上了一课&#xff…

作者头像 李华
网站建设 2026/4/18 8:18:28

树莓派运行 DeepSeek 大模型实战:轻量化模型选型与内存占用控制精要

树莓派运行 DeepSeek 大模型实战:轻量化模型选型与内存占用控制精要引言树莓派(Raspberry Pi)以其低廉的价格、强大的社区支持和丰富的扩展性,成为了嵌入式开发、教育、物联网和边缘计算的热门平台。随着人工智能(AI&a…

作者头像 李华
网站建设 2026/4/18 5:38:46

Flutter UI 性能优化实践

. 布局优化核心目标是减少布局计算量,避免布局重排(Relayout),提升布局效率。1. 懒加载减少布局计算‌作用阶段:布局阶段。优化逻辑:通过 Sliver 架构按需渲染可见区域子项,避免一次性计算所有子…

作者头像 李华
网站建设 2026/4/18 8:19:36

外网访问开源语音克隆工具 GPT-SoVITS

GPT-SoVITS 是一款开源的跨语言语音合成工具,结合了 GPT 和 SoVITS 的合成技术,在少量样本条件下实现语音克隆与合成。具有多种功能:极简样本需求、跨语言支持、全流程语音处理工具链等。应用在影视配音、有声内容创作、教育等多个领域。本文…

作者头像 李华
网站建设 2026/3/27 5:27:47

c#造个轮子-取色器TakeColor(附源码)

缘由看过上篇文章《OpenCvSharp基于颜色反差规避FBA面单贴标&#xff08;2&#xff09;》的都应该有印象这么一行代码&#xff1a;// 面单颜色列表&#xff08;十六进制格式&#xff09; privatestaticreadonly List<string> LabelColors new List<string> { …

作者头像 李华