使用Python和Matplotlib模拟3D海浪动画

news2024/10/25 8:46:11

使用Python和Matplotlib模拟3D海浪动画

在计算机图形学和动画领域,模拟逼真的海洋表面一直是一个具有挑战性的问题。本文将介绍如何使用Python的Matplotlib库和Gerstner波浪模型,创建一个动态的3D海浪动画。通过叠加多个波浪,我们可以生成复杂而真实的海洋效果。

前言

Gerstner波浪模型是一种经典的海浪模拟方法,具有计算简单和效果逼真的特点。它通过对海面上的每个点施加正弦波的位移,来模拟波浪的起伏。本文将详细解释代码的实现过程,并提供可运行的示例代码。

环境准备

首先,确保您的环境中安装了以下库:

  • numpy
  • matplotlib

可以使用以下命令安装:

pip install numpy matplotlib

代码实现

1. 导入必要的库

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
  • numpy用于数值计算和数组操作。
  • matplotlib.pyplot用于绘制图形。
  • matplotlib.animation用于创建动画。

2. 设置海洋网格参数

nx, ny = 200, 200  # 网格大小
x = np.linspace(-10, 10, nx)
y = np.linspace(-10, 10, ny)
X, Y = np.meshgrid(x, y)
  • 创建一个二维网格,用于表示海洋表面的坐标点。
  • 网格越密集,生成的海浪细节越丰富。

3. 设置Gerstner波浪参数

wave_amplitude = 1.0     # 波浪振幅
wave_length = 5.0        # 波长
wave_speed = 1.0         # 波速
num_waves = 5            # 波浪数量
directions = np.linspace(0, 2 * np.pi, num_waves, endpoint=False)
phases = np.random.uniform(0, 2 * np.pi, num_waves)
  • num_waves决定了叠加多少个波浪,以增加海浪的复杂度。
  • directions定义了每个波浪的传播方向,均匀分布在0到2π之间。
  • phases为每个波浪生成一个随机的初始相位。

4. 创建图形和3D坐标轴

fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')
  • 创建一个图形窗口,并添加一个3D坐标轴用于绘制海浪表面。

5. 设置绘图参数

ax.set_xlim(-10, 10)
ax.set_ylim(-10, 10)
ax.set_zlim(-3, 3)
ax.set_xticks([])
ax.set_yticks([])
ax.set_zticks([])
ax.view_init(elev=30, azim=225)
  • 设置坐标轴的范围和视角。
  • 隐藏坐标轴的刻度,使图形更加简洁。

6. 定义动画更新函数

def animate(frame):
    ax.clear()
    Z = np.zeros_like(X)
    t = frame / 20.0  # 时间参数

    for i in range(num_waves):
        direction = directions[i]
        phase = phases[i]
        k = 2 * np.pi / wave_length
        omega = k * wave_speed

        dir_x = np.cos(direction)
        dir_y = np.sin(direction)

        phi = k * (dir_x * X + dir_y * Y) - omega * t + phase
        Z += wave_amplitude / num_waves * np.cos(phi)

    surf = ax.plot_surface(X, Y, Z, cmap='Blues', linewidth=0, antialiased=True)

    ax.set_xlim(-10, 10)
    ax.set_ylim(-10, 10)
    ax.set_zlim(-3, 3)
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_zticks([])
    ax.view_init(elev=30, azim=225)
    return surf,
  • animate函数用于更新每一帧的图像。
  • t是时间参数,控制波浪的动态变化。
  • 在循环中,叠加多个Gerstner波浪。
  • 使用ax.plot_surface绘制3D海浪表面。

7. 创建动画

ani = animation.FuncAnimation(fig, animate, frames=200, interval=30, blit=False)
  • 使用FuncAnimation创建动画。
  • frames=200表示总共生成200帧。
  • interval=30表示每帧之间的间隔为30毫秒。

8. 显示动画

plt.show()
  • 显示生成的海浪动画。

运行效果

运行上述代码后,将会出现一个窗口,展示动态的3D海浪动画。波浪在不断地起伏,模拟了真实的海洋表面。由于叠加了多个不同方向和相位的波浪,海浪看起来更加复杂和逼真。
在这里插入图片描述下面是-gif动图
在这里插入图片描述

深入理解Gerstner波浪模型

Gerstner波浪模型通过对海面上的每个点施加位移,来模拟波浪的传播。对于二维情况下,海面上某一点的位移可以表示为:

Z = A cos ⁡ ( k x − ω t + ϕ ) Z = A \cos(kx - \omega t + \phi) Z=Acos(kxωt+ϕ)

  • ( A ):振幅
  • ( k ):波数,( k = \frac{2\pi}{\lambda} ),其中( \lambda )为波长
  • ( \omega ):角频率,( \omega = k \cdot c ),其中( c )为波速
  • ( \phi ):初始相位

在代码中,我们对多个波浪进行叠加,每个波浪具有不同的传播方向和初始相位。这使得海浪的形状更加复杂多变。

参数调整

您可以通过修改以下参数来改变海浪的效果:

  • wave_amplitude:增大振幅会使波浪更高。
  • wave_length:改变波长会影响波浪的密集程度。
  • wave_speed:改变波速会影响波浪传播的速度。
  • num_waves:增加波浪数量会使海浪更复杂。

例如,将波浪数量增加到10:

num_waves = 10

运行后,您会发现海浪的细节更加丰富。
完整代码如下:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.mplot3d import Axes3D

# 设置海洋网格参数
nx, ny = 200, 200  # 网格大小,值越大,细节越丰富
x = np.linspace(-10, 10, nx)
y = np.linspace(-10, 10, ny)
X, Y = np.meshgrid(x, y)

# Gerstner波浪参数
wave_amplitude = 1.0     # 波浪振幅
wave_length = 5.0        # 波长
wave_speed = 1.0         # 波速
num_waves = 5            # 波浪数量,叠加多个波浪以增加复杂度
directions = np.linspace(0, 2 * np.pi, num_waves, endpoint=False)  # 波浪传播方向
phases = np.random.uniform(0, 2 * np.pi, num_waves)                # 随机初始相位

# 创建图形和3D坐标轴
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')

# 设置绘图参数
ax.set_xlim(-10, 10)
ax.set_ylim(-10, 10)
ax.set_zlim(-3, 3)
ax.set_xticks([])
ax.set_yticks([])
ax.set_zticks([])
ax.view_init(elev=30, azim=225)  # 视角角度,可根据需要调整

# 初始化海浪高度
Z = np.zeros_like(X)

# 动画更新函数
def animate(frame):
    ax.clear()
    Z = np.zeros_like(X)
    t = frame / 20.0  # 时间参数,控制动画速度

    # 叠加多个Gerstner波浪
    for i in range(num_waves):
        direction = directions[i]
        phase = phases[i]
        k = 2 * np.pi / wave_length  # 波数
        omega = k * wave_speed       # 角频率

        # 波浪传播方向的单位向量
        dir_x = np.cos(direction)
        dir_y = np.sin(direction)

        # 计算偏移
        phi = k * (dir_x * X + dir_y * Y) - omega * t + phase
        Z += wave_amplitude / num_waves * np.cos(phi)

    # 绘制海浪表面
    surf = ax.plot_surface(X, Y, Z, cmap='Blues', linewidth=0, antialiased=True)

    # 设置绘图参数
    ax.set_xlim(-10, 10)
    ax.set_ylim(-10, 10)
    ax.set_zlim(-3, 3)
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_zticks([])
    ax.view_init(elev=30, azim=225)
    return surf,

# 创建动画
ani = animation.FuncAnimation(fig, animate, frames=200, interval=30, blit=False)

# 显示动画
plt.show()

结论

本文介绍了如何使用Python和Matplotlib库,基于Gerstner波浪模型,创建一个动态的3D海浪动画。通过对代码的逐步讲解,相信您已经理解了其中的原理和实现方法。您可以尝试调整参数,甚至扩展代码,实现更多有趣的效果。

参考资料

  • Gerstner Waves on Wikipedia
  • Matplotlib 3D Surface Plot Documentation
  • NumPy Meshgrid Function

希望本文对您有所帮助,祝您在数据可视化和动画制作的道路上取得更多成果!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2223132.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

行为设计模式 -命令模式- JAVA

命令模式 一.简介二. 案例2.1 接收者(Receiver)2.2 命令接口实现对象(ConcreteCommand)2.3 调用者( invoker)2.4 获取Receiver对象2. 5 装配者客户端测试 三. 结论3.1 要点3.2 示例 一.简介 百度百科&…

HarmonyOS第一课——HarmonyOS介绍

HarmonyOS第一课 HarmonyOS介绍 HarmonyOS是新一代的智能终端操作系统(泛终端服务的载体); 智慧互联协同,全场景交互体验; 核心技术理念: 一次开发 多次部署: 预览 可视化开发UI适配 事件交…

Go 语言基础教程:6.条件判断

在这篇教程中,我们将通过一个简单的 Go 语言程序来学习条件判断结构的使用。以下是我们要分析的代码: package mainimport "fmt"func main() {if 7%2 0 {fmt.Println("7 is even")} else {fmt.Println("7 is odd")}if 8…

C++基础;来点人机交互

我们当然不能只满足单纯的输出&#xff0c;当打开一个编程的大门&#xff0c;宣告自己来时&#xff0c;我们更愿意看到它也能作出反应。 #include<iostream> #include<vector> #include<string> #include<algorithm> #include<cmath>using nam…

js基础入门篇

1.输出语句&#xff0c;内部样式&#xff0c;外部样式&#xff0c;数组定义 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.…

操作系统Linux指令

1.注册表文件是Windows操作系统中的一种特殊文件&#xff0c;主要用于存储系统设置和用户配置信息。 这些文件通过REG文件扩展名进行标识&#xff0c;用户可以通过双击REG文件将其内容导入注册表中&#xff0c;从而对系统设置进行修改。 REG文件的特点是功能强大、灵活&#xf…

Linux -- 进程间通信、初识匿名管道

目录 进程间通信 什么是进程间通信 进程间通信的一般规律 前言&#xff1a; 管道 代码预准备&#xff1a; 如何创建管道 -- pipe 函数 参数&#xff1a; 返回值&#xff1a; wait 函数 参数&#xff1a; 验证管道的运行&#xff1a; 源文件 test.c &#xff1a; m…

Python•for

很高兴认识你 for列表字典打印字典默认打印格式控制格式打印字典 定义输入与打印拓展 range()函数元组集合 加油站&#x1f970; 都是用示例帮助理解哦~ 代码都只给图片哦&#xff0c;本人亲身经历&#xff0c;自己手敲会注意到更多细节&#x1fae7; 一起进步吧&#x1f970; …

(二十二)、k8s 中的关键概念

文章目录 1、总体概览2、第一层&#xff1a;物理机、集群、Node、Pod 之间的关系2、第二层&#xff1a;命名空间 Namespace3、定义4、控制平面&#xff08;Control Plane&#xff09;5、特别的概念 Service6、Deployment 经过 之前几篇文章对 k8s 的实践&#xff0c;结合实践&…

立仪科技:光谱共焦传感器在玻璃领域的革命性突破

光谱共焦传感器&#xff0c;一种基于光谱共焦原理的高精度位移测量装置&#xff0c;近年来在玻璃等透明材料的厚度测量和表面形貌检测中展现出了巨大的应用潜力。立仪科技小编将深入探讨光谱共焦传感器在玻璃测量中的技术优势&#xff0c;并分析其解决方案。 一、光谱共焦传感器…

庆祝程序员节:聊一聊编程语言的演变

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

毕业设计 基于STM32单片机健康检测/老人防跌倒系统 心率角度检测GSM远程报警 (程序+原理图+元件清单全套资料)

文章目录 前言一、主要功能介绍二、硬件设计硬件实物展示 三、软件设计四、总结资料与实物获取方式 前言 近年来&#xff0c;毕业设计和答辩的要求与难度逐渐加大&#xff0c;传统的毕业设计题目往往缺乏创新性和亮点&#xff0c;难以满足毕业答辩的标准。 为了帮助大家顺利完…

STM32L476芯片在KEIL环境下BOOT跳转APP注意事项

BOOT工程 分配BOOT程序地址、设置参数地址、APP程序地址、下载缓冲区地址 #define BOOT_SECTOR_ADDR 0x08000000 #define BOOT_SECTOR_SIZE 0x0000A000 #define SETTING_SECTOR_ADDR 0x0800A000 #define SETTING_SECTOR_SIZE 0x00002000 #define APP_S…

Spring Boot:植物健康监测的智能管家

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

python——数据类型(数字,字符串)

&#xff08;一&#xff09;基本知识 首先我们需要知道&#xff0c;在python中数据类型大体可以分为两类 1.基本数据类型&#xff1a;数字和字符串 2.复合数据类型&#xff1a;列表&#xff0c;元组&#xff0c;字典&#xff0c;集合 &#xff08;二&#xff09;基本数据类型 …

LabVIEW水质监测系统

在面对全球性的海洋污染问题时&#xff0c;利用先进技术进行水质监测成为了保护海洋环境的关键手段之一。开发了一种基于LabVIEW的海洋浮标水质监测系统&#xff0c;该系统能够实时监测并评估近海水域的水质状况&#xff0c;旨在为海洋保护和污染防治提供科技支持。 项目背景 …

【数据结构】专栏开篇 | 1024程序员节

专栏说明&#xff1a;本专栏用于数据结构复习&#xff0c;文章中出现的代码由C语言实现&#xff0c;在专栏中会涉及到部分OJ题目&#xff0c;如对你学习有所帮助&#xff0c;可以点赞鼓励一下博主喔~~~&#x1f493; 博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a…

关于bp抓不到本地包

关于bp抓不到本地包 关于bp抓不到本地包 关于bp抓不到本地包 pikachu练习时&#xff0c;发现用bp抓本地&#xff08;127.0.0.1&#xff09;数据包时&#xff0c;竟然直接放行访问。 是因为系统默认127.0.0.1无法使用代理&#xff0c;因此bp才抓不到本地数据包&#xff0c;需要…

vue中为什么data属性在实例中可以定义成对象,而在组件中定义成对象会抛出错误

在vue组件中将data属性定义成对象会报错 为什么data属性在实例中可以定义成对象&#xff0c;而在组件中定义成对象则会抛出错误&#xff1f; Vue 实例中的 data 属性&#xff1a; 当 data 被定义在一个单一的 Vue 实例中时&#xff0c;这个实例通常是全局唯一的&#xff0c…

数据结构笔记(其七)--树(二叉树)

目录 1.知识总览 2.二叉树的基本概念 &#xff08;1&#xff09;.满二叉树 &#xff08;2&#xff09;.完全二叉树 &#xff08;3&#xff09;.二叉排序树 &#xff08;4&#xff09;.平衡二叉树 3.二叉树常考点 i.叶子结点与二分支结点的数量关系 ii.第i 层的最多结点数&…