2023-05-30 22:02:19 发布
网友
我正在寻找一种方法,用python绘制几个(O(1))3D箭头,这些箭头是“正确的3D”,我的意思是沿着Mathematica的结果,即箭头的杆看起来像一个管子。在
我在matplotlib文档中找不到任何东西,但肯定有办法吗?在
可以从二维中定义的某个路径创建旋转实体,以创建三维箭头。下面的代码将其封装到一个函数中,该函数允许指定一些箭头参数。这允许创建要使用的路径。然后围绕z轴旋转,创建一个三维箭头。为了允许箭头在空间中的任意方向,可以先绕x轴再绕z轴旋转整个箭头(theta_x,theta_z)。最后使用plot_surface绘制箭头。注意,放置箭头的轴应该具有相等的纵横比,这样箭头就不会倾斜。在
theta_x
theta_z
plot_surface
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D def arrow3d(ax, length=1, width=0.05, head=0.2, headwidth=2, theta_x=0, theta_z=0, offset=(0,0,0), **kw): w = width h = head hw = headwidth theta_x = np.deg2rad(theta_x) theta_z = np.deg2rad(theta_z) a = [[0,0],[w,0],[w,(1-h)*length],[hw*w,(1-h)*length],[0,length]] a = np.array(a) r, theta = np.meshgrid(a[:,0], np.linspace(0,2*np.pi,30)) z = np.tile(a[:,1],r.shape[0]).reshape(r.shape) x = r*np.sin(theta) y = r*np.cos(theta) rot_x = np.array([[1,0,0],[0,np.cos(theta_x),-np.sin(theta_x) ], [0,np.sin(theta_x) ,np.cos(theta_x) ]]) rot_z = np.array([[np.cos(theta_z),-np.sin(theta_z),0 ], [np.sin(theta_z) ,np.cos(theta_z),0 ],[0,0,1]]) b1 = np.dot(rot_x, np.c_[x.flatten(),y.flatten(),z.flatten()].T) b2 = np.dot(rot_z, b1) b2 = b2.T+np.array(offset) x = b2[:,0].reshape(r.shape); y = b2[:,1].reshape(r.shape); z = b2[:,2].reshape(r.shape); ax.plot_surface(x,y,z, **kw) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') arrow3d(ax) arrow3d(ax, length=2, width=0.02, head=0.1, headwidth=1.5, offset=[1,1,0], theta_x=40, color="crimson") arrow3d(ax, length=1.4, width=0.03, head=0.15, headwidth=1.8, offset=[1,0.1,0], theta_x=-60, theta_z = 60, color="limegreen") ax.set_xlim(0,1) ax.set_ylim(0,1) ax.set_zlim(0,1) plt.show()
可以从二维中定义的某个路径创建旋转实体,以创建三维箭头。下面的代码将其封装到一个函数中,该函数允许指定一些箭头参数。这允许创建要使用的路径。然后围绕z轴旋转,创建一个三维箭头。为了允许箭头在空间中的任意方向,可以先绕x轴再绕z轴旋转整个箭头(
theta_x
,theta_z
)。最后使用plot_surface
绘制箭头。注意,放置箭头的轴应该具有相等的纵横比,这样箭头就不会倾斜。在相关问题 更多 >
编程相关推荐