Python中的“Tube”箭头

2024-04-19 12:13:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一种方法,用python绘制几个(O(1))3D箭头,这些箭头是“正确的3D”,我的意思是沿着Mathematica的结果,即箭头的杆看起来像一个管子。在

我在matplotlib文档中找不到任何东西,但肯定有办法吗?在

3D Arrow as generated by mathematica


Tags: 方法文档matplotlib绘制箭头管子办法mathematica
1条回答
网友
1楼 · 发布于 2024-04-19 12:13:07

可以从二维中定义的某个路径创建旋转实体,以创建三维箭头。下面的代码将其封装到一个函数中,该函数允许指定一些箭头参数。这允许创建要使用的路径。然后围绕z轴旋转,创建一个三维箭头。为了允许箭头在空间中的任意方向,可以先绕x轴再绕z轴旋转整个箭头(theta_xtheta_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()

enter image description here

相关问题 更多 >