“管"Python中的箭头 [英] "Tube" Arrows in Python

查看:64
本文介绍了“管"Python中的箭头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种方法来用python绘制几条(O(1))3D箭头,它们是适当的3D",通过它我的意思是与Mathematica产生的直线相似,即,箭头的杆看起来像管子一样.

I am looking for a way to draw a few (O(1)) 3D arrows with python, which are "proper 3D", by which I mean something along the lines of what Mathematica yields, i.e. rod of the arrow looks like a tube.

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

I did not find anything in the matplotlib documentation, but surely there must be a way?

推荐答案

您可以从2D中定义的某些路径创建旋转实体,以创建3D箭头.以下代码将其包装到一个函数中,该函数允许指定一些箭头参数.这允许创建要使用的路径.然后绕z轴旋转,创建3D箭头.为了允许箭头在空间中任意定向,然后可以使整个箭头绕x轴旋转,然后绕z轴( theta_x theta_z )旋转.最后,使用 plot_surface 绘制箭头.请注意,放置箭头的轴应具有相等的长宽比,以使箭头不会偏斜.

You may create a solid of revolution from some path defined in 2D to create a 3D arrow. The following code wraps this into a function, which allows to specify some of the arrow parameters. This allows to create the path to be used. This is then revolved about the z axis, creating a 3D arrow. To allow for arbitrary orientations of the arrow in space, one may then rotate the complete arrow about the x axis and then about the z axis (theta_x, theta_z). Finally the arrow is plotted using a plot_surface. Note that the axes into which the arrow is placed should have an equal aspect, such that the arrow is not skewed.

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()

这篇关于“管"Python中的箭头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆