炫酷粒子系统动画实战:Matplotlib实现银河漩涡效果

效果演示:银河粒子漩涡

动态特征​:

  1. 500个粒子组成旋转星云,呈现螺旋轨迹运动​
  2. 粒子颜色随速度渐变(蓝->紫->红)
  3. 粒子尺寸根据离心力动态变化
  4. 背景呈现深空渐变效果

在这里插入图片描述
在这里插入图片描述

核心代码分析

1. 粒子系统初始化

class ParticleSystem:
    def __init__(self, n=500):
        # 极坐标参数初始化
        self.theta = np.linspace(0, 8*np.pi, n)
        self.r = np.linspace(0, 1, n)**0.5  # 半径非线性分布
        
        # 动态参数
        self.dr = np.random.uniform(0.95, 1.05, n)  # 半径变化因子
        self.speed = np.random.uniform(0.8, 1.2, n) # 角速度差异
        self.size = 10 * np.sin(self.theta)**2 + 1  # 初始尺寸
        
        # 转换为笛卡尔坐标
        self.x = self.r * np.cos(self.theta)
        self.y = self.r * np.sin(self.theta)

关键技术点​:

  • 使用极坐标构建初始分布,r**0.5实现中心密集效果
  • speed参数控制粒子角速度差异,产生层次感
  • sin(theta)^2尺寸计算创建波浪形大小分布

2. 动画更新函数

def update(frame):
    # 半径动态变化(模拟离心力)
    ps.r *= ps.dr  
    ps.r = np.clip(ps.r, 0, 2)  # 限制最大半径
    
    # 角度持续增加(形成旋转)
    ps.theta += 0.02 * ps.speed
    
    # 坐标更新
    ps.x = ps.r * np.cos(ps.theta)
    ps.y = ps.r * np.sin(ps.theta)
    
    # 颜色和尺寸更新
    colors = plt.cm.plasma((ps.r/2 + frame/100) % 1)  # 动态色相
    sizes = 50 * np.abs(np.sin(0.5*ps.theta + frame/20)) + 1
    
    # 更新散点图属性
    scatter.set_offsets(np.c_[ps.x, ps.y])
    scatter.set_color(colors)
    scatter.set_sizes(sizes)
    
    return scatter,

核心算法​:

  • clip函数限制粒子扩散范围
  • plasma颜色映射结合帧数实现动态渐变
  • set_offsets高效更新所有粒子位置(比逐点更新快10倍+)

3. 渲染优化技巧

# 使用TkAgg后端提升性能
import matplotlib
matplotlib.use('TkAgg')  

# 创建深空渐变背景
gradient = np.linspace(0, 1, 256).reshape(1, -1)
ax.imshow(gradient, aspect='auto', cmap='plasma', 
          extent=[-2.5, 2.5, -2.5, 2.5], alpha=0.15)

# 开启blitting加速
ani = animation.FuncAnimation(fig, update, interval=20, 
                             blit=True, cache_frame_data=False)

性能优化​:

  • TkAgg后端支持硬件加速
  • imshow创建静态渐变背景,减少重复渲染
  • cache_frame_data=False避免内存泄漏

完整实现代码

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.colors import Normalize

class ParticleSystem:
    def __init__(self, n=500):
        self.theta = np.linspace(0, 8*np.pi, n)
        self.r = np.linspace(0, 1, n)**0.5
        self.dr = np.random.uniform(0.95, 1.05, n)
        self.speed = np.random.uniform(0.8, 1.2, n)
        self.size = 10 * np.sin(self.theta)**2 + 1
        self.x = self.r * np.cos(self.theta)
        self.y = self.r * np.sin(self.theta)

# 初始化画布
fig, ax = plt.subplots(figsize=(8,8), facecolor='black')
ax.axis('off')
ax.set_xlim(-2.5, 2.5)
ax.set_ylim(-2.5, 2.5)

# 创建渐变背景
gradient = np.linspace(0, 1, 256).reshape(1, -1)
ax.imshow(gradient, aspect='auto', cmap='plasma', 
         extent=[-2.5, 2.5, -2.5, 2.5], alpha=0.15)

# 初始化粒子系统
ps = ParticleSystem()
scatter = ax.scatter(ps.x, ps.y, c=ps.r, cmap='plasma', 
                    s=ps.size, alpha=0.7, edgecolors='none')

def update(frame):
    ps.r = np.clip(ps.r * ps.dr, 0, 2)
    ps.theta += 0.02 * ps.speed
    ps.x = ps.r * np.cos(ps.theta)
    ps.y = ps.r * np.sin(ps.theta)
    
    colors = plt.cm.plasma((ps.r/2 + frame/100) % 1)
    sizes = 50 * np.abs(np.sin(0.5*ps.theta + frame/20)) + 1
    
    scatter.set_offsets(np.c_[ps.x, ps.y])
    scatter.set_color(colors)
    scatter.set_sizes(sizes)
    
    return scatter,

# 运行动画
ani = animation.FuncAnimation(fig, update, frames=200, 
                            interval=20, blit=True, cache_frame_data=False)

# 保存动画(可选)
# ani.save('galaxy.mp4', writer='ffmpeg', dpi=120, extra_args=['-vcodec', 'libx264'])

plt.show()

Matplotlib的动画模块介绍

模块名​:matplotlib.animation
​作用​:生成动态可视化,支持保存为GIF、视频或实时交互显示。

​核心类对比

类名适用场景核心机制优点缺点
FuncAnimation动态生成帧(逐帧更新)通过函数回调更新图形元素内存高效,适合复杂动画需要手动编写更新逻辑
ArtistAnimation预渲染所有帧后播放直接绘制预先生成的艺术家对象简单易用,适合静态帧序列内存占用高,不适合大数据

核心功能分点

FuncAnimation 主要参数

  • fig: 画布对象

  • func: 更新图形的回调函数(每帧调用)

  • frames: 帧数据(可迭代对象或生成器)

  • init_func: 初始化函数(可选)

  • interval: 帧间隔时间(毫秒,默认200)

  • blit: 是否启用优化渲染(仅重绘变化部分)

ArtistAnimation 主要参数

  • fig: 画布对象

  • artists: 包含每帧艺术家对象(如线条、图像)的列表

注意事项

​依赖项​:

  • 保存视频需安装外部库(如ffmpeg或imagemagick)
  • 在Jupyter中显示动画需添加%matplotlib notebook或使用HTML(anim.to_html5_video())

​性能优化​:

  • 启用blit=True可显著提升渲染速度
  • 避免在回调函数中重复创建对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

像素艺术家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值