如何用Python3 Matplotlib绘制函数3+2x-x²的多轴旋转体(含三种方法)
绘制$y=3+2x-x^2$绕不同轴的旋转体
不需要求反函数也能实现所有旋转体的绘制,针对四个旋转轴,我们可以通过坐标变换或直接利用函数的取值范围来构建3D曲面,以下是完整实现代码:
核心思路
- 绕x轴/平行x轴的直线:固定x坐标,将y方向的距离作为半径在垂直于x轴的平面旋转
- 绕y轴/平行y轴的直线:对于二次函数的双值x,分左右两支生成坐标,再绕y轴旋转;或通过坐标平移转换为绕坐标轴旋转的问题
完整代码
import matplotlib.pyplot as plt import numpy as np n = 100 # 定义原函数的x范围(零点在x=-1和x=3,顶点x=1) x = np.linspace(-1, 3, n) y = 3 + 2*x - x**2 theta = np.linspace(0, 2*np.pi, n) # 创建画布,2行4列布局:左列是2D曲线,右列是对应旋转体 fig = plt.figure(figsize=(16, 8)) # -------------------------- # a. 绕x轴旋转 # -------------------------- ax1 = fig.add_subplot(2, 4, 1) ax1.plot(x, y, color='#1f77b4') ax1.set_title('原曲线') ax1.grid(True) ax1_3d = fig.add_subplot(2, 4, 2, projection='3d') # 构建旋转曲面:x不变,y和z由y*cosθ、y*sinθ生成 X, Theta = np.meshgrid(x, theta) Y = y[:, np.newaxis] * np.cos(Theta) Z = y[:, np.newaxis] * np.sin(Theta) ax1_3d.plot_surface(X, Y, Z, cmap='viridis', alpha=0.7) ax1_3d.set_title('绕x轴旋转体') # -------------------------- # b. 绕y轴旋转 # -------------------------- ax2 = fig.add_subplot(2, 4, 3) ax2.plot(x, y, color='#ff7f0e') ax2.set_title('原曲线') ax2.grid(True) ax2_3d = fig.add_subplot(2, 4, 4, projection='3d') # 二次函数的反函数是双值:x = 1 ± √(4 - y),先取y的范围0到4 y_vals = np.linspace(0, 4, n) x_left = 1 - np.sqrt(4 - y_vals) x_right = 1 + np.sqrt(4 - y_vals) # 左支旋转 X_left = x_left[:, np.newaxis] * np.cos(Theta) Z_left = x_left[:, np.newaxis] * np.sin(Theta) Y_left = np.tile(y_vals[:, np.newaxis], (1, n)) ax2_3d.plot_surface(X_left, Y_left, Z_left, cmap='plasma', alpha=0.7) # 右支旋转 X_right = x_right[:, np.newaxis] * np.cos(Theta) Z_right = x_right[:, np.newaxis] * np.sin(Theta) Y_right = np.tile(y_vals[:, np.newaxis], (1, n)) ax2_3d.plot_surface(X_right, Y_right, Z_right, cmap='plasma', alpha=0.7) ax2_3d.set_title('绕y轴旋转体') # -------------------------- # c. 绕直线y=-1旋转 # -------------------------- ax3 = fig.add_subplot(2, 4, 5) ax3.plot(x, y, color='#2ca02c') ax3.axhline(y=-1, color='gray', linestyle='--') ax3.set_title('原曲线与旋转轴y=-1') ax3.grid(True) ax3_3d = fig.add_subplot(2, 4, 6, projection='3d') # 坐标变换:将旋转轴平移到y=0,旋转后再平移回去 distance_to_axis = y + 1 # 每个点到y=-1的距离 X_rot = np.tile(x[:, np.newaxis], (1, n)) Y_rot = -1 + distance_to_axis[:, np.newaxis] * np.cos(Theta) Z_rot = distance_to_axis[:, np.newaxis] * np.sin(Theta) ax3_3d.plot_surface(X_rot, Y_rot, Z_rot, cmap='inferno', alpha=0.7) ax3_3d.set_title('绕y=-1旋转体') # -------------------------- # d. 绕直线x=4旋转 # -------------------------- ax4 = fig.add_subplot(2, 4, 7) ax4.plot(x, y, color='#d62728') ax4.axvline(x=4, color='gray', linestyle='--') ax4.set_title('原曲线与旋转轴x=4') ax4.grid(True) ax4_3d = fig.add_subplot(2, 4, 8, projection='3d') # 坐标变换:将旋转轴平移到x=0,旋转后再平移回去 distance_to_axis = 4 - x # 每个点到x=4的距离 X_rot = 4 - distance_to_axis[:, np.newaxis] * np.cos(Theta) Y_rot = np.tile(y[:, np.newaxis], (1, n)) Z_rot = distance_to_axis[:, np.newaxis] * np.sin(Theta) ax4_3d.plot_surface(X_rot, Y_rot, Z_rot, cmap='magma', alpha=0.7) ax4_3d.set_title('绕x=4旋转体') plt.tight_layout() plt.show()
代码说明
- 绕x轴:直接利用原函数的y值作为旋转半径,在y-z平面生成圆周,x坐标保持不变
- 绕y轴:二次函数在y∈[0,4]时对应两个x值,分别生成左右两支的旋转曲面并拼接
- 绕y=-1:先计算每个点到旋转轴的垂直距离,将旋转轴平移到坐标轴后完成旋转,再平移回原位置
- 绕x=4:同理,计算点到旋转轴的距离,平移坐标轴后旋转,再还原坐标
内容的提问来源于stack exchange,提问作者Freya the Goddess
相关产品推荐
相关产品推荐

