在三维空间几何建模中,过原点的多个平面与圆柱面的交线问题广泛存在于机械设计、计算机图形学以及工程制图等领域。本文围绕一个具体的几何构型展开深入探讨:给定四个均通过坐标原点的平面,其法向量由参数 β\betaβ、α1\alpha_1α1 和 α2\alpha_2α2 共同决定,同时存在一个以原点 ooo 为端面圆心、轴线沿 xxx 轴正方向的圆柱。我们将系统地推导这四个平面的法向量表达式,计算相邻平面两两相交产生的四条交线方向,分析这些交线在 yozyozyoz 投影面上的迹线特征,并最终通过 Python 代码实现三维空间构造与二维投影的可视化。

首先建立坐标系与参数约定。设 zzz 轴为水平方向,yyy 轴为竖直方向,xxx 轴垂直于纸面向里,构成右手直角坐标系。圆柱的端面圆心位于原点 ooo,轴线沿 xxx 轴正方向,直径 D=0.256D = 0.256D=0.256,因此半径 R=D/2=0.128R = D/2 = 0.128R=D/2=0.128。四个平面的法向量由以下参数生成:β=25∘\beta = 25^\circβ=25∘,α1=10∘\alpha_1 = 10^\circα1=10∘,α2=30∘\alpha_2 = 30^\circα2=30∘。根据定义,四个法向量分别为:
n1=(cosβcosα1, sinα1, −sinβcosα1) \mathbf{n}_1 = (\cos\beta\cos\alpha_1,\ \sin\alpha_1,\ -\sin\beta\cos\alpha_1) n1=(cosβcosα1, sinα1, −sinβcosα1)
n2=(cosβcosα2, −sinα2, sinβcosα2) \mathbf{n}_2 = (\cos\beta\cos\alpha_2,\ -\sin\alpha_2,\ \sin\beta\cos\alpha_2) n2=(cosβcosα2, −sinα2, sinβcosα2)
n3=(cosβcosα1, −sinα1, sinβcosα1) \mathbf{n}_3 = (\cos\beta\cos\alpha_1,\ -\sin\alpha_1,\ \sin\beta\cos\alpha_1) n3=(cosβcosα1, −sinα1, sinβcosα1)
n4=(cosβcosα2, sinα2, −sinβcosα2) \mathbf{n}_4 = (\cos\beta\cos\alpha_2,\ \sin\alpha_2,\ -\sin\beta\cos\alpha_2) n4=(cosβcosα2, sinα2, −sinβcosα2)
代入数值计算可得各法向量的具体分量。n1=(0.8925, 0.1736, −0.4162)\mathbf{n}_1 = (0.8925,\ 0.1736,\ -0.4162)n1=(0.8925, 0.1736, −0.4162),n2=(0.7849, −0.5000, 0.3660)\mathbf{n}_2 = (0.7849,\ -0.5000,\ 0.3660)n2=(0.7849, −0.5000, 0.3660),n3=(0.8925, −0.1736, 0.4162)\mathbf{n}_3 = (0.8925,\ -0.1736,\ 0.4162)n3=(0.8925, −0.1736, 0.4162),n4=(0.7849, 0.5000, −0.3660)\mathbf{n}_4 = (0.7849,\ 0.5000,\ -0.3660)n4=(0.7849, 0.5000, −0.3660)。容易验证,n3\mathbf{n}_3n3 与 n1\mathbf{n}_1n1 关于 xozxozxoz 平面镜像对称,n4\mathbf{n}_4n4 与 n2\mathbf{n}_2n2 同样关于 xozxozxoz 平面镜像对称。由于四个平面均通过原点,其平面方程统一为 n⋅(x,y,z)=0\mathbf{n} \cdot (x, y, z) = 0n⋅(x,y,z)=0。
接下来计算相邻平面的交线。由于所有平面均过原点,任意两个平面的交线必为一条过原点的直线,其方向向量由两平面法向量的叉积给出。定义四条交线如下:
L12=n1×n2=(−0.1633, −0.7364, −0.6571) \mathbf{L}_{12} = \mathbf{n}_1 \times \mathbf{n}_2 = (-0.1633,\ -0.7364,\ -0.6571) L12=n1×n2=(−0.1633, −0.7364, −0.6571)
L23=n2×n3=(−0.0596, −0.7364, 0.6742) \mathbf{L}_{23} = \mathbf{n}_2 \times \mathbf{n}_3 = (-0.0596,\ -0.7364,\ 0.6742) L23=n2×n3=(−0.0596, −0.7364, 0.6742)
L34=n3×n4=(0.1633, 0.7364, 0.6571) \mathbf{L}_{34} = \mathbf{n}_3 \times \mathbf{n}_4 = (0.1633,\ 0.7364,\ 0.6571) L34=n3×n4=(0.1633, 0.7364, 0.6571)
L41=n4×n1=(0.0596, 0.7364, −0.6742) \mathbf{L}_{41} = \mathbf{n}_4 \times \mathbf{n}_1 = (0.0596,\ 0.7364,\ -0.6742) L41=n4×n1=(0.0596, 0.7364, −0.6742)
观察可知,L34=−L12\mathbf{L}{34} = -\mathbf{L}{12}L34=−L12,L41=−L23\mathbf{L}{41} = -\mathbf{L}{23}L41=−L23,这意味着四条交线实际上构成两对平行且共线的直线,在空间中形成一个平行四边形的截面轮廓。进一步计算平面之间的夹角,以 n1\mathbf{n}_1n1 与 n2\mathbf{n}2n2 为例,夹角 θ12\theta{12}θ12 满足:
θ12=arccos(n1⋅n2∥n1∥∥n2∥)=62.50∘ \theta_{12} = \arccos\left(\frac{\mathbf{n}_1 \cdot \mathbf{n}_2}{\|\mathbf{n}_1\|\|\mathbf{n}_2\|}\right) = 62.50^\circ θ12=arccos(∥n1∥∥n2∥n1⋅n2)=62.50∘
类似地,n2\mathbf{n}_2n2 与 n3\mathbf{n}_3n3 的夹角为 55.00∘55.00^\circ55.00∘,n3\mathbf{n}_3n3 与 n4\mathbf{n}_4n4 的夹角为 62.50∘62.50^\circ62.50∘,n4\mathbf{n}_4n4 与 n1\mathbf{n}_1n1 的夹角为 55.00∘55.00^\circ55.00∘。
现在考虑这些几何元素在 yozyozyoz 面上的投影。投影方向平行于 xxx 轴,因此三维空间中的点 (x,y,z)(x, y, z)(x,y,z) 投影到 yozyozyoz 面上即为 (y,z)(y, z)(y,z)。圆柱面所有点的投影填满以原点为圆心、半径为 RRR 的圆形区域,而端面圆本身位于 x=0x=0x=0 平面上,其方程直接为:
y2+z2=R2 y^2 + z^2 = R^2 y2+z2=R2
对于过原点的平面 n⋅(x,y,z)=0\mathbf{n} \cdot (x, y, z) = 0n⋅(x,y,z)=0,其在 yozyozyoz 面上的迹线可通过令 x=0x=0x=0 得到,即:
nyy+nzz=0⇒z=−nynzy n_y y + n_z z = 0 \quad \Rightarrow \quad z = -\frac{n_y}{n_z}y nyy+nzz=0⇒z=−nznyy
因此,四条交线在 yozyozyoz 面上的投影即为各自所在平面的迹线,均为过原点的直线。具体而言,n1\mathbf{n}_1n1 对应的迹线角度为 24.69∘24.69^\circ24.69∘,n2\mathbf{n}_2n2 对应 −53.79∘-53.79^\circ−53.79∘,n3\mathbf{n}_3n3 对应 135.31∘135.31^\circ135.31∘,n4\mathbf{n}_4n4 对应 126.21∘126.21^\circ126.21∘。这四条迹线将端面圆分割为八个扇形区域,清晰地反映了空间平面与圆柱端面的相对方位关系。
为了直观验证上述推导,下面给出完整的 Python 实现代码。该代码利用 NumPy 进行向量运算,使用 Matplotlib 绘制三维空间中的平面交线、圆柱面以及 yozyozyoz 投影。
python
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# ========== 参数设置 ==========
beta = np.deg2rad(25)
alpha1 = np.deg2rad(10)
alpha2 = np.deg2rad(30)
R = 0.256 / 2 # 圆柱半径
L = 0.30 # 圆柱可视化半长
# ========== 法向量计算 ==========
def compute_normal(beta, alpha, sy, sz):
"""根据参数计算法向量"""
return np.array([
np.cos(beta) * np.cos(alpha),
sy * np.sin(alpha),
sz * np.sin(beta) * np.cos(alpha)
])
n1 = compute_normal(beta, alpha1, 1, -1)
n2 = compute_normal(beta, alpha2, -1, 1)
n3 = compute_normal(beta, alpha1, -1, 1)
n4 = compute_normal(beta, alpha2, 1, -1)
normals = [n1, n2, n3, n4]
labels = ['n1', 'n2', 'n3', 'n4']
# ========== 四条交线方向 ==========
# L12 = n1 × n2, L23 = n2 × n3, L34 = n3 × n4, L41 = n4 × n1
lines_dir = []
lines_dir.append(np.cross(n1, n2))
lines_dir.append(np.cross(n2, n3))
lines_dir.append(np.cross(n3, n4))
lines_dir.append(np.cross(n4, n1))
line_labels = ['L12 (n1∩n2)', 'L23 (n2∩n3)', 'L34 (n3∩n4)', 'L41 (n4∩n1)']
line_colors = ['red', 'green', 'magenta', 'orange']
# 单位化交线方向
for i in range(len(lines_dir)):
lines_dir[i] = lines_dir[i] / np.linalg.norm(lines_dir[i])
# ========== 圆柱面采样 ==========
theta = np.linspace(0, 2*np.pi, 200)
x_range = np.linspace(0, L, 30)
Xc, Tc = np.meshgrid(x_range, theta)
Yc = R * np.cos(Tc)
Zc = R * np.sin(Tc)
# 端面圆 (x=0)
Ye = R * np.cos(theta)
Ze = R * np.sin(theta)
# ========== 图1: 3D 可视化 ==========
fig = plt.figure(figsize=(14, 6))
# 左子图:3D 线框与圆柱
ax1 = fig.add_subplot(121, projection='3d')
# 绘制圆柱面
ax1.plot_surface(Xc, Yc, Zc, color='lightgray', alpha=0.2, edgecolor='none')
# 绘制端面圆
ax1.plot(np.zeros_like(Ye), Ye, Ze, 'b-', linewidth=2.5, label='端面圆 (x=0)')
# 绘制四条交线
t = np.linspace(-L, L, 50)
for (d, lb, c) in zip(lines_dir, line_labels, line_colors):
ax1.plot(t*d[0], t*d[1], t*d[2], color=c, linewidth=2.5, label=lb)
# 绘制方向箭头
ax1.quiver(0, 0, 0, d[0]*0.15, d[1]*0.15, d[2]*0.15,
color=c, arrow_length_ratio=0.3, linewidth=2)
# 标注法向量
for n, lb in zip(normals, labels):
ax1.quiver(0, 0, 0, n[0]*0.1, n[1]*0.1, n[2]*0.1,
color='black', arrow_length_ratio=0.2, linewidth=1.5)
ax1.text(n[0]*0.11, n[1]*0.11, n[2]*0.11, lb, fontsize=12, weight='bold')
ax1.set_xlabel('x (垂直纸面向里)')
ax1.set_ylabel('y (竖直)')
ax1.set_zlabel('z (水平)')
ax1.set_title('3D: 四平面交线与圆柱', fontsize=13)
ax1.set_box_aspect([1, 1, 1])
ax1.legend(loc='upper left', fontsize=8)
# 右子图:yz 投影
ax2 = fig.add_subplot(122)
# 圆柱在 yz 面的投影(圆)
ax2.plot(Ze, Ye, 'b-', linewidth=2.5, label='圆柱投影 (圆 R=0.128)')
# 四条交线的 yz 投影(迹线)
y_trace = np.linspace(-R*1.6, R*1.6, 100)
for (n, lb, c) in zip(normals, labels, line_colors):
if abs(n[2]) > 1e-6:
z_trace = -(n[1] / n[2]) * y_trace
ax2.plot(z_trace, y_trace, '--', color=c, linewidth=2, label=f'{lb} 投影')
else:
ax2.axhline(0, color=c, linestyle='--', linewidth=2, label=f'{lb} 投影')
ax2.set_xlabel('z (水平)')
ax2.set_ylabel('y (竖直)')
ax2.set_aspect('equal')
ax2.grid(True, alpha=0.3)
ax2.axhline(0, color='k', linewidth=0.5)
ax2.axvline(0, color='k', linewidth=0.5)
ax2.set_title('yoz 面投影:迹线与端面圆', fontsize=13)
ax2.legend(fontsize=8, loc='best')
plt.tight_layout()
plt.savefig('four_planes_cylinder.png', dpi=150, bbox_inches='tight')
plt.show()
# ========== 数值输出 ==========
print("=" * 65)
print(f"{'法向':<8} {'x':>10} {'y':>10} {'z':>10} {'模长':>10}")
print("-" * 65)
for n, lb in zip(normals, labels):
print(f"{lb:<8} {n[0]:>10.4f} {n[1]:>10.4f} {n[2]:>10.4f} {np.linalg.norm(n):>10.4f}")
print("\n" + "=" * 65)
print(f"{'交线':<15} {'dx':>10} {'dy':>10} {'dz':>10}")
print("-" * 65)
for d, lb in zip(lines_dir, line_labels):
print(f"{lb:<15} {d[0]:>10.4f} {d[1]:>10.4f} {d[2]:>10.4f}")
print("\n平面间夹角:")
for i in range(4):
for j in range(i+1, 4):
angle = np.rad2deg(np.arccos(np.clip(
np.dot(normals[i], normals[j]) /
(np.linalg.norm(normals[i]) * np.linalg.norm(normals[j])), -1, 1)))
)
print(f" {labels[i]}-{labels[j]}: {angle:.2f}°")
print("\nyz 面迹线角度(从 z 轴正向逆时针):")
for n, lb in zip(normals, labels):
angle = np.rad2deg(np.arctan2(n[2], n[1]))
print(f" P({lb}): {angle:.2f}°")
运行上述代码后,将得到包含三维空间构造与二维投影的综合图像。三维图中可以清晰地看到四条过原点的交线从圆柱内部穿过,端面圆与法向量箭头共同标定了空间方位;投影图则准确地展示了四条迹线将圆形端面分割为八个扇形的几何关系。整个推导与实现过程验证了镜像对称法向量导致的交线共线特性,以及平面与圆柱相交的椭圆截线在投影面上的退化规律。这一完整的几何分析框架可直接推广至其他参数配置或更复杂的多平面交线问题中。