在Python中用2个点和2个角度绘制一条线这是变形的光束

问题描述

我试图绘制一条线,该线具有2个点和2个角度,分别对应于先前笔直的变形线(请参见下图)。点的坐标和角度都来自函数。我尝试使用matplotlib注释(使用angle3,但不允许AngleAAngleB中的变量并且不允许相反的角度)和Bezier曲线,但是我无法找到指定角度的方法

由我要绘制的变形线组成的框架:

Frame made of the deformed lines that I want to draw

解决方法

在下文中,我假设OP关心的线是仅在节点中加载的梁,证明使用三次样条线是合理的。

下面的函数displ根据未变形和变形的节点位置以及节点旋转来计算沿线的31个点的位移位置(可能过大),并对横向位移应用可选的缩放因子。它会返回(2,31)阵列在全局坐标系中的位移光束位置。

from numpy import linspace
_s = linspace(0,1,31) # non-dimensional abscissa
_s0,_s1 = (_s-1)**2*_s,(_s-1)*_s**2 # cubic splines for unit rotations

def displ(X0,Y0,X1,Y1,x0,y0,x1,y1,φ0,φ1,f=1.0,ξ=_s,ξ0=_s0,ξ1=_s1):
    
    from numpy import arctan2 as atan2,array,cos,sin,sqrt

    # rigid slopes before and after
    Θ,θ = atan2(Y1-Y0,X1-X0),atan2(y1-y0,x1-x0)
    # rigid rotation (difference in slopes,after - before)
    δ = θ - Θ
    # end rotations not explained by the rigid rotation
    dφ0,dφ1 = φ0-δ,φ1-δ
    # transversal displacements,ξ0 and ξ1 are the proper cubic splines
    ν = dφ0*ξ0 + dφ1*ξ1
    # deformed length,sine and cosine for projection
    l = sqrt((x1-x0)**2+(y1-y0)**2)
    cs,sn = cos(θ),sin(θ)

    # u,axial displacement,u = l*ξ
    # v,transversal disp.t,v = l*ν
    # dx,dy = T @ {u,v}
    x0y0 = array((x0,y0),dtype=float)[:,None]
    return x0y0+l*array(((cs,-sn),(sn,cs)))@array((ξ,f*ν)) # shape(2,31)

要检查实现的正确性并显示用法,我使用displ编写了一个简短的程序来显示4个任意变形的形状。

import matplotlib.pyplot as plt
X0,y0 = 0.0,0.0,0.0
#             X1    Y1    x1    y1    f0    f1
args_list = [( 0,5,0.2,4.8,0.17,0.12),( 5,5.2,-0.2,-.14,0.18),4.7,0.18,-.22),-5,-5.3,-.20,0.00)]

fig,axes = plt.subplots(2,2,constrained_layout=1)
for ax,(X1,f0,f1) in zip(axes.flatten(),args_list):
    ax.set_title('φ₀ = %+4.2f,φ₁ = %+4.2f'%(f0,f1))
    ax.plot((X0,X1),(Y0,Y1),alpha=0.35)
    ax.plot(*displ(X0,f1))
    ax.set_aspect(1)
    ax.grid(1)
plt.show()

4 deformed lines