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

使用Matplotlib绘制3D超球时p≠1仅显示部分图形的修复咨询

修复Matplotlib绘制p≠1时的3D超球图形不完整问题

我尝试用Python的Matplotlib绘制3D超球,超球是通过形状参数p定义的圆角立方体通用图形,p=1时为球体。根据文献,超球的修改球坐标定义为:

x = rcos(u)(1/p) * sin(v)(1/p)
y = r
sin(u)(1/p) * sin(v)(1/p)
z = r*cos(v)**(1/p)
其中u=phi,v=theta

但代码在p=1时能生成完整球体,p取其他值(如2)时仅显示部分图形,需要从数学层面修复。

问题原因

核心问题是负数的分数次幂在实数域无意义:当p≠1时,1/p为分数,numpy对负数计算分数次幂会返回NaN。比如u在(π/2, 3π/2)区间时cos(u)为负、sin(u)在(π, 2π)区间为负,v在(π/2, π)区间时cos(v)为负,这些位置的计算结果都会变成NaN,导致对应区域的图形缺失。

解决方案

保留三角函数的符号,同时对绝对值进行幂运算。将每个三角函数的幂运算拆分为符号提取 + 绝对值的幂运算,避免NaN产生。

修改后的完整代码

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(projection='3d')

r, p = 1, 2  # 可修改p值测试,比如3、0.5等

# 生成网格数据
u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)
u, v = np.meshgrid(u, v)

# 修复后的坐标计算:保留符号,对绝对值取幂
cos_u = np.cos(u)
sin_u = np.sin(u)
sin_v = np.sin(v)
cos_v = np.cos(v)

x = r * np.sign(cos_u) * np.abs(cos_u)**(1/p) * np.sign(sin_v) * np.abs(sin_v)**(1/p)
y = r * np.sign(sin_u) * np.abs(sin_u)**(1/p) * np.sign(sin_v) * np.abs(sin_v)**(1/p)
z = r * np.sign(cos_v) * np.abs(cos_v)**(1/p)

# 绘制曲面
ax.plot_surface(x, y, z, cmap='viridis')

# 调整视角,方便观察完整图形
ax.view_init(elev=30, azim=45)
plt.show()

补充说明

  • 无论p取任何正数(包括小于1的情况,比如p=0.5),修改后的代码都能生成完整的超球图形
  • 可通过修改cmap参数调整颜色风格,或添加edgecolor='none'去掉网格线,让图形更平滑
  • 当p趋近于无穷大时,超球会趋近于立方体;p<1时,图形会呈现“尖刺”状的超球形态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:30:44