我怎样才能在另一条线上停止 pyplot 线?

问题描述

Plot of lines not crossing over the AB line

你好!有没有人知道使用 matpltolib 实现类似于图表显示内容?我需要绘制一些不跨越给定线 AB 的线,例如 CC' 和 DD'。有什么办法可以做到这一点吗?

解决方法

从点 C 画一条线,垂直于线 AB 并停在 AB 处,可以计算出投影点 P。 P 应该在 AB 上,所以 P = t*A + (1-t)*B。这个点方程意味着它应该同时适用于 x 和 y 坐标:xp = t * xa + (1 - t) * xbyp = t * ya + (1 - t) * yb) 对于某些 t。 P 也应该在一条包含 C 的直线上,并以垂直矢量为方向。垂直向量是yb - ya,- (xb - xa)。所以,P = C + u * Perp 为一些 u

Sympy,Python 的符号数学库可用于求解这些方程:


from sympy import symbols,Eq,solve

t,u,xa,ya,xb,yb,xc,yc = symbols('t u xa ya xb yb xc yc ')

eqpx = Eq(xc + u * (yb - ya),t * xa + (1 - t) * xb)
eqpy = Eq(yc + u * (xa - xb),t * ya + (1 - t) * yb)

solution = solve([eqpx,eqpy])

发现:

{t: -(xa*xb - xa*xc - xb**2 + xb*xc + ya*yb - ya*yc - yb**2 + yb*yc)/(xa**2 - 2*xa*xb + xb**2 + ya**2 - 2*ya*yb + yb**2),u: (xa*yb - xa*yc - xb*ya + xb*yc + xc*ya - xc*yb)/(xa**2 - 2*xa*xb + xb**2 + ya**2 - 2*ya*yb + yb**2)}

该解决方案可用于定义将点 C 投影到线 AB 上的函数。下面是一个例子:

from matplotlib import pyplot as plt

def project_on_line(xc,yc,yb):
    t = -(xa * xb - xa * xc - xb ** 2 + xb * xc + ya * yb - ya * yc - yb ** 2 + yb * yc) / (
                xa ** 2 - 2 * xa * xb + xb ** 2 + ya ** 2 - 2 * ya * yb + yb ** 2)
    return t * xa + (1 - t) * xb,t * ya + (1 - t) * yb

def show_point(x,y,name):
    plt.text(x,f' {name}',ha='left',va='top')

xa,ya = 0,2
xb,yb = 6,5
xc,yc = 5,1
xd,yd = 7,0
xcp,ycp = project_on_line(xc,yb)
xdp,ydp = project_on_line(xd,yd,yb)
show_point(xa,"A")
show_point(xb,"B")
show_point(xc,"C")
show_point(xcp,ycp,"C'")
show_point(xd,"D")
show_point(xdp,ydp,"D'")

plt.plot([xa,xb],[ya,yb],color='dodgerblue')
plt.plot([xc,xcp],[yc,ycp],color='dodgerblue')
plt.plot([xd,xdp],[yd,ydp],color='dodgerblue')
plt.axis('equal')

plt.show()

example plot