1、画圆柱面
import sympy as sy
from sympy.plotting import plot3d_parametric_surface
# 定义变量和参数
u, v = sy.symbols('u v') # 参数
r = 2 # 圆柱半径
h = 5 # 圆柱高度
# 定义圆柱面方程
x = r * sy.cos(u) # x 的参数方程
y = r * sy.sin(u) # y 的参数方程
z = v # z 的参数方程
# 绘制圆柱面的图像
p = plot3d_parametric_surface(x, y, z, (u, 0, 2*sy.pi), (v, -h/2, h/2), show=False)
p.show()
2.画圆柱面与平面的交线
import sympy as sy
from sympy.plotting import plot3d_parametric_line
# 定义变量和参数
u, v = sy.symbols('u v') # 参数
r = 2 # 圆柱半径
h = 5 # 圆柱高度
theta = sy.pi/4 # 平面的角度参数
# 定义圆柱面方程
x1 = r * sy.cos(u) # x 的参数方程
y1 = r * sy.sin(u) # y 的参数方程
z1 = v # z 的参数方程
# 定义平面方程
y2, z2 = sy.symbols('y2 z2')
eq_plane = sy.Eq(z2, sy.tan(theta) * y2)
# 求解交点的坐标
intersection_points = sy.solve([eq_plane.subs({y2: y1, z2: z1})], v)
# 绘制交点曲线
p = plot3d_parametric_line(x1, y1, z1.subs({v:intersection_points[v]}), (u, 0, 2*sy.pi), show=False)
p.show()
3、显示圆柱面、平面及其交线
import sympy as sy
from sympy.plotting import plot3d_parametric_line, plot3d_parametric_surface
# 定义变量和参数
u, v = sy.symbols('u v') # 参数
r = 2 # 圆柱半径
h = 5 # 圆柱高度
theta = sy.pi/4 # 平面的角度参数
# 定义圆柱面方程
x1 = r * sy.cos(u) # x 的参数方程表达式
y1 = r * sy.sin(u) # y 的参数方程表达式
z1 = v # z 的参数方程表达式
# 定义平面方程
x2, y2, z2 = sy.symbols('x2 y2 z2')
eq_plane = sy.Eq(z2, sy.tan(theta) * y2)
# 求解交点的坐标
intersection_points = sy.solve([eq_plane.subs({y2: y1, z2: z1})], v)
# 绘制交点曲线
p = plot3d_parametric_line(x1, y1, z1.subs({v: intersection_points[v]}), (u, 0, 2*sy.pi), line_color='green',
line_alpha=1, linestyle='-', line_width=20, show=False)
p.title = 'Intersection Curve'
p.xlabel = 'x'
p.ylabel = 'y'
p.zlabel = 'z'
# 绘制圆柱面
cylinder = plot3d_parametric_surface(x1, y1, z1, (u, 0, 2*sy.pi), (v, 0, h), surface_color=(0, 0, 1, 0.5), show=False)
cylinder.title = 'Cylinder Surface'
cylinder.xlabel = 'x'
cylinder.ylabel = 'y'
cylinder.zlabel = 'z'
# 绘制平面
plane = plot3d_parametric_surface(x2, y2, sy.tan(theta) * y2, (x2, -r, r), (y2, -r, r), line_color='red',
surface_color=(1, 0, 0, 0.5), show=False)
plane.title = 'Plane'
plane.xlabel = 'x'
plane.ylabel = 'y'
plane.zlabel = 'z'
p.extend(cylinder)
p.extend(plane)
p.show()
4、绘制交线在指定平面的投影
import sympy as sy
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle
# 定义变量和参数
u, v = sy.symbols('u v') # 参数
x, y, z = sy.symbols('x y z')
r = 2 # 圆柱半径
h = 5 # 圆柱高度
theta = sy.pi/4 # 平面的角度参数
a, b, c, d = 1, 1, 1, 3 # 平面方程参数
# 定义圆柱面方程
x1 = r * sy.cos(u) # x 的参数方程表达式
y1 = r * sy.sin(u) # y 的参数方程表达式
z1 = v # z 的参数方程表达式
# 定义平面方程
x2, y2, z2 = sy.symbols('x2 y2 z2')
eq_plane = sy.Eq(z2, sy.tan(theta) * y2)
# 定义投影平面方程
plane_eq = sy.Eq(a*x + b*y + c*z + d, 0)
# 求解交点的坐标
intersection_points = sy.solve([eq_plane.subs({y2: y1, z2: z1})], v)
# 将符号表达式转换为NumPy函数
fx1 = sy.lambdify(u, x1, modules=['numpy'])
fy1 = sy.lambdify(u, y1, modules=['numpy'])
fz1 = sy.lambdify(u, z1.subs({v: intersection_points[v]}), modules=['numpy'])
# 计算交点
u_vals = np.linspace(0, 2*np.pi, 100)
x_vals = fx1(u_vals)
y_vals = fy1(u_vals)
z_vals = fz1(u_vals)
# 计算交点投影坐标
intersection_projections = []
for x_val,y_val,z_val in zip(x_vals,y_vals,z_vals):
# 计算交点到平面的最短距离
distance = np.abs(a * x_val + b * y_val + c * z_val + d) / np.sqrt(a ** 2 + b ** 2 + c ** 2)
# 计算平移方向与最短距离的一致性
direction = 1 if (distance < 0) else -1
# 将平面的法向量乘以最短距离的绝对值并进行平移,得到投影点在平面上的坐标
projection_x = x_val + direction * abs(a) * abs(distance)
projection_y = y_val + direction * abs(b) * abs(distance)
projection_z = z_val + direction * abs(c) * abs(distance)
intersection_projections.append([projection_x, projection_y, projection_z])
intersection_projections=np.array(intersection_projections)
# 绘制点集
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 投影前的点集
ax.scatter(x_vals,y_vals,z_vals, color='blue', label='Before Projection')
# 投影后的点集
ax.scatter(intersection_projections[:,0], intersection_projections[:,1], intersection_projections[:,2], color='red', label='After Projection')
# 定义平面上的坐标范围
x_range = np.linspace(-10, 10, 10)
y_range = np.linspace(-10, 10, 10)
xx, yy = np.meshgrid(x_range, y_range)
# 计算平面上的z坐标
zz = (-a * xx - b * yy - d) / c
# 绘制投影平面
ax.plot_surface(xx, yy, zz, alpha=0.5, facecolor='green', label='Projection Plane')
# 设置坐标轴标签
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
# 创建自定义图例
before_projection_legend = Line2D([0], [0], marker='o', color='blue', linestyle='None', label='Before Projection')
after_projection_legend = Line2D([0], [0], marker='o', color='red', linestyle='None', label='After Projection')
projection_plane_legend = Rectangle((0, 0), 1, 1, fc='green', alpha=0.5, label='Projection Plane')
# 添加自定义图例到图形中
ax.legend(handles=[before_projection_legend, after_projection_legend, projection_plane_legend], facecolor='white')
# 显示图形
plt.show()