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

如何在Matplotlib中绘制缠绕球面的丝带?

在Matplotlib中绘制球面缠绕丝带的问题

我尝试在Matplotlib中绘制缠绕球面的丝带,但未得到预期效果。预期效果为球面表面环绕的带状区域(类似螺旋缠绕的丝带覆盖球面部分区域),目前仅画出了一条螺旋曲线,无法形成带状面。

原代码

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

# 球坐标转笛卡尔坐标函数
# 球坐标可更简便地表示球面
def sferiche_a_cartesiane(r, theta, phi): # r为半径,theta为余纬度
    x = r * np.sin(phi) * np.cos(theta)
    y = r * np.sin(phi) * np.sin(theta)
    z = r * np.cos(phi)
    return x, y, z

# 生成球面的球坐标,使用等间距numpy数组
theta_sfera = np.linspace(0, 2 * np.pi, 100)
phi_sfera = np.linspace(0, np.pi, 50)
theta_sfera, phi_sfera = np.meshgrid(theta_sfera, phi_sfera) # 生成网格坐标

# 设置球面半径
raggio_sfera = 1.0 

# 将球坐标转换为笛卡尔坐标
x_sfera, y_sfera, z_sfera = sferiche_a_cartesiane(raggio_sfera, theta_sfera, phi_sfera)

# 创建3D绘图的画布和坐标轴
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# 绘制球面
ax.plot_surface(x_sfera, y_sfera, z_sfera, color='r', alpha=0.1, edgecolors=None, zorder=0)

t = np.linspace(-1, 1, 1000) # t ∈ [-1, 1]
# 生成半径略大的参数曲线,基于球面方程x**2 + y**2 + z**2 = 1推导
x_curva = 1.01 * ((1 - t**2)**0.5) * np.cos(10 * np.pi * t)
y_curva = 1.01 * ((1 - t**2)**0.5) * np.sin(10 * np.pi * t)
z_curva = 1 * t

# 绕球面旋转参数曲线
angolo_rotazione = np.pi / 4 
x_rotato = x_curva * np.cos(angolo_rotazione) - y_curva * np.sin(angolo_rotazione)
y_rotato = x_curva * np.sin(angolo_rotazione) + y_curva * np.cos(angolo_rotazione)
z_rotato = z_curva

# 绘制旋转后的参数曲线
ax.plot(x_rotato, y_rotato, z_rotato, 'y', linewidth=2, zorder=1)

# 设置坐标轴标签
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

# 显示图形
plt.show()

当前问题

运行上述代码后,仅能看到一条黄色螺旋曲线,无法形成预期的带状曲面。

解决方案

要生成带状区域,需要构造一组平行的螺旋路径并将其转换为网格曲面。核心修改点如下:

  1. 定义丝带宽度参数,生成多个偏移角度的螺旋路径
  2. 将所有路径点组合成网格,使用plot_surface绘制曲面
  3. 确保丝带的所有点都贴合球面

修改后的完整代码

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

# 球坐标转笛卡尔坐标函数
def sferiche_a_cartesiane(r, theta, phi):
    x = r * np.sin(phi) * np.cos(theta)
    y = r * np.sin(phi) * np.sin(theta)
    z = r * np.cos(phi)
    return x, y, z

# 生成球面
theta_sfera = np.linspace(0, 2 * np.pi, 100)
phi_sfera = np.linspace(0, np.pi, 50)
theta_sfera, phi_sfera = np.meshgrid(theta_sfera, phi_sfera)
raggio_sfera = 1.0
x_sfera, y_sfera, z_sfera = sferiche_a_cartesiane(raggio_sfera, theta_sfera, phi_sfera)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(x_sfera, y_sfera, z_sfera, color='r', alpha=0.1, edgecolors=None, zorder=0)

# 丝带参数设置
t = np.linspace(-1, 1, 1000)
num_strips = 20  # 丝带包含的平行曲线数量
ribbon_width = 0.15  # 丝带宽度(弧度)
radius = 1.01  # 丝带略大于球面半径

# 生成丝带的网格参数
phi_ribbon = np.arccos(t)  # 对应球面的余纬度
theta_base = 10 * np.pi * t  # 基础螺旋角度
theta_offset = np.linspace(-ribbon_width/2, ribbon_width/2, num_strips)  # 宽度方向的偏移

# 构造丝带的网格坐标
theta_grid, phi_grid = np.meshgrid(theta_base + theta_offset[:, np.newaxis], phi_ribbon)
x_ribbon = radius * np.sin(phi_grid) * np.cos(theta_grid)
y_ribbon = radius * np.sin(phi_grid) * np.sin(theta_grid)
z_ribbon = radius * np.cos(phi_grid)

# 旋转丝带
angolo_rotazione = np.pi / 4
x_rotato = x_ribbon * np.cos(angolo_rotazione) - y_ribbon * np.sin(angolo_rotazione)
y_rotato = x_ribbon * np.sin(angolo_rotazione) + y_ribbon * np.cos(angolo_rotazione)
z_rotato = z_ribbon

# 绘制丝带曲面
ax.plot_surface(x_rotato, y_rotato, z_rotato, color='y', alpha=0.7, zorder=1)

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()

代码说明

  • 用meshgrid生成了丝带的网格坐标,将单条曲线扩展为一组平行的螺旋路径
  • 通过theta_offset控制丝带的宽度,调整ribbon_width可以改变丝带的宽窄
  • 用plot_surface绘制丝带曲面,设置alpha参数保证球面和丝带都可见

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 01:51:01