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

如何在Matplotlib中移除3D平面与悬链面相交的圆形区域?

解决Matplotlib 3D绘图中平面与悬链面相交区域的遮挡问题

要实现平面不遮挡悬链面开口的效果,我们可以直接硬编码悬链面与平面的交线(圆形),然后在平面网格中排除圆内区域,生成带镂空的平面。

修改后的完整代码

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

# 悬链面参数方程
def catenoid(u, v, a=1):
    x = a * np.cosh(u/a) * np.cos(v)
    y = a * np.cosh(u/a) * np.sin(v)
    z = u
    return x, y, z

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

# 创建绘图对象
fig = plt.figure(figsize=(12, 12))
ax = fig.add_subplot(111, projection="3d", computed_zorder=False)
ax.set_box_aspect(aspect=(6, 4, 3))
ax.set_axis_off()

# 绘制第一个悬链面
x1, y1, z1 = catenoid(u, v)
surf1 = ax.plot_surface(x1, y1, z1, cmap='viridis', edgecolor='grey', alpha=0.5, vmin=-2, vmax=2)

# 绘制偏移后的第二个悬链面
x2, y2, z2 = catenoid(u, v)
x2_offset = x2 + 8
surf2 = ax.plot_surface(x2_offset, y2, z2, cmap='viridis', edgecolor='grey', alpha=0.5, vmin=-2, vmax=2)

# 计算悬链面在z=±2处的圆形截面半径
a = 1
r = a * np.cosh(2/a)

# 生成带镂空的底部平面(z=-2)
xx, yy = np.meshgrid(np.linspace(-5, 13, 100), np.linspace(-5, 5, 100))
zz = np.full_like(xx, -2)
# 掩码:排除两个悬链面对应的圆内区域
mask1 = (xx**2 + yy**2) > r**2
mask2 = ((xx - 8)**2 + yy**2) > r**2
mask_bottom = mask1 & mask2
ax.plot_surface(xx[mask_bottom], yy[mask_bottom], zz[mask_bottom], zorder=-1, alpha=0.5, cmap='viridis', edgecolor='none', vmin=-2, vmax=2)

# 生成带镂空的顶部平面(z=2)
zz = np.full_like(xx, 2)
mask_top = mask1 & mask2
ax.plot_surface(xx[mask_top], yy[mask_top], zz[mask_top], zorder=1, alpha=0.5, cmap='viridis', edgecolor='none', vmin=-2, vmax=2)

plt.show()

关键说明

  • 悬链面在z=±2处的截面是标准圆形,半径由参数方程推导为r = a*cosh(2/a),此处a=1,半径约为3.762
  • 通过创建布尔掩码,过滤掉平面网格中两个悬链面圆形区域内的点,只保留圆外部分进行绘制
  • 最终平面会在悬链面开口位置形成圆形镂空,完全露出悬链面的结构,符合预期视觉效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 00:26:21