You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在轴对称3D曲面的截面上叠加2D流线图?

3D轴对称系统矢量场可视化方案

需求概述

  • 针对3D轴对称球体系统,已在x-z平面求解得到矢量场并生成2D流线图
  • 基于轴对称性,将2D解绕z轴旋转得到完整3D矢量场
  • 期望可视化效果:绘制裁剪掉x>0且y<0区域的3D曲面,在裁剪后露出的两个平面(y=0且x>0、x=0且y<0)上叠加原2D流线图
  • 优先选择连续流线图:因矢量场结构复杂,相比离散箭头(quiver),流线图更易展现整体分布

实现步骤

1. 3D曲面裁剪

在生成球体上下部分的网格时,添加条件判断,将X>0且Y<0的网格点设为np.nan,从而去除该区域的曲面渲染。

2. 流线图的3D投影

  • y=0且x>0平面:直接复用x-z平面的流线数据,将所有点的y坐标设为0,在3D坐标系中绘制流线
  • x=0且y<0平面:利用轴对称性,将x-z平面中x≥0的流线数据进行坐标转换:x→-y,y→0,保持z不变,得到y-z平面(y≤0)的流线数据后绘制

3. 层级与样式控制

通过zorder参数将流线图置于曲面上方,确保流线清晰可见;保留原2D流线的色彩与密度设置,保证可视化一致性

完整可复现代码

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from scipy.interpolate import griddata

ell = 0.62
gamma = 1
Rbase, Rcap, center = 0.62, 0.62, 0

###################
###### 预处理矢量场数据(生成x-z平面插值后的矢量场)
res = 200

x_Car = [[-1.8417224772056704e-16, -0.0, -0.5726312223685197],
 [7.597102430294396e-17, 0.0, -0.6203504908994001],
 [0.020037100834806584, 0.0, -0.5857436781333181],
 [0.030439155856322415, 0.0, -0.6196032515649681],
 [0.020156894294067102, 0.0, -0.5477190352848064],
 [-1.6882456041048852e-16, -0.0, -0.5249119538377125]]
m_Car = [[-1.60647705e-05,  0.00000000e+00, -2.43349475e-01],
 [ 0.00022923,  0.        , -0.21359168],
 [ 0.00627664,  0.        , -0.23712676],
 [ 0.01131077,  0.        , -0.21533309],
 [ 0.00655443,  0.        , -0.25987232],
 [ 2.65801174e-05,  0.00000000e+00, -2.72980539e-01]]

m_Car_T, x_Car_T = np.array(m_Car).T, np.array(x_Car).T

cm = matplotlib.cm.coolwarm
norm = matplotlib.colors.Normalize(vmin=0,vmax=1)
sm = matplotlib.cm.ScalarMappable(cmap=cm, norm=norm)

xx, zz = x_Car_T[0], x_Car_T[2]
x_grid, z_grid = np.meshgrid(np.linspace(xx.min(),xx.max(),res),np.linspace(zz.min(),zz.max(),res))

# 插值得到x-z平面的矢量场分量
x_vector_interp = griddata((xx, zz), m_Car_T[0], (x_grid, z_grid), method='cubic')
z_vector_interp = griddata((xx, zz), m_Car_T[2], (x_grid, z_grid), method='cubic')

###################
###### 3D可视化:裁剪曲面 + 叠加流线图
width, height = matplotlib.figure.figaspect(1.2)*1.5
fig, ax = plt.subplots(1, 1, figsize=(width, height), subplot_kw={"projection": "3d"})

### 绘制上半球(Cap)并裁剪x>0且y<0区域
theta, phi = np.mgrid[0:np.pi/2:180j, 0:1.5*np.pi:270j]
X = Rcap*np.sin(theta)*np.cos(phi)
Y = Rcap*np.sin(theta)*np.sin(phi)
Z = Rcap*np.cos(theta)+center
# 裁剪条件:x>0且y<0的区域设为nan
mask = (X > 0) & (Y < 0)
Z[mask] = np.nan
ax.plot_surface(X/ell, Y/ell, Z/ell, linewidth=0, antialiased=False, 
                rstride=1, cstride=1, color='grey')

### 绘制下半球(Base)并裁剪x>0且y<0区域
theta, phi = np.mgrid[np.pi/2:np.pi:180j, 0:1.5*np.pi:270j]
X = Rbase*np.sin(theta)*np.cos(phi)
Y = Rbase*np.sin(theta)*np.sin(phi)
Z = Rbase*np.cos(theta)
# 裁剪条件:x>0且y<0的区域设为nan
mask = (X > 0) & (Y < 0)
Z[mask] = np.nan
ax.plot_surface(X/ell, Y/ell, Z/ell, linewidth=0, antialiased=False, 
                rstride=1, cstride=1, color='gainsboro')

### 绘制中心轴
ax.plot([0,0],[0,0],[-Rbase/ell,(Rcap+center)/ell],'k-',zorder=100)

### 叠加y=0且x>0平面的流线图
# 提取x>0的网格区域
x_pos_mask = x_grid > 0
x_stream = x_grid[x_pos_mask]/ell
z_stream = z_grid[x_pos_mask]/ell
u_stream = x_vector_interp[x_pos_mask]
v_stream = z_vector_interp[x_pos_mask]
# 在3D中绘制流线,y坐标固定为0
ax.streamplot(x_stream, np.zeros_like(x_stream), z_stream, u_stream, np.zeros_like(u_stream), v_stream,
              color='k', density=1.1, zorder=200)

### 叠加x=0且y<0平面的流线图
# 利用轴对称性转换坐标:x→-y,y→0,z保持不变
# 提取x≥0的网格区域(避免重复)
x_nonneg_mask = x_grid >= 0
# 转换坐标:原x变为-y(y<0),原y=0变为x=0
y_stream = -x_grid[x_nonneg_mask]/ell
z_stream = z_grid[x_nonneg_mask]/ell
# 矢量分量转换:原x分量变为-y分量,原z分量不变
u_stream = np.zeros_like(x_vector_interp[x_nonneg_mask])
v_stream = -x_vector_interp[x_nonneg_mask]
w_stream = z_vector_interp[x_nonneg_mask]
# 在3D中绘制流线,x坐标固定为0
ax.streamplot(np.zeros_like(y_stream), y_stream, z_stream, u_stream, v_stream, w_stream,
              color='k', density=1.1, zorder=200)

### 设置坐标轴标签与比例
ax.set_xlabel('$x/\ell$'); ax.set_ylabel('$y/\ell$'); ax.set_zlabel('$z/\ell$')
ax.set_box_aspect([1,1,(2*Rbase)/(Rbase+Rcap-center)])

# 添加颜色条
fig.colorbar(sm, label=r'$|\mathbf{m}|$', pad=0.1)

plt.show()

替代优化方案

如果需要更直观的3D流线展示,可直接将x-z平面的流线绕z轴旋转生成3D流线束:

  • 取x-z平面的单条流线,生成多个角度的旋转副本,形成环绕z轴的流线管
  • 配合曲面透明度调整,可同时展现内部矢量场分布与外部曲面形态

内容的提问来源于stack exchange,提问作者pamgur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 14:59:53