平面线相交

问题描述

我正在努力寻找解决方案来用python编码问题。 我有这些红色和蓝色曲线(它们只是python中的点列表)。我想在红线上找到紫色的点。

enter image description here

因此,我认为解决此问题的方法是找到与每个红点之间的线和由蓝线的每个点处的切向量形成的平面相交的点:

enter image description here

问题是当我尝试用python在列表中的每个点求解此简单方程式时,我最终找到了放置错误的绿色点。 这是我的代码

blue_curve = [[0.0,1050.45881]
       [54.4012659,1050.45924]
       [108.772202,1050.46115]
       [163.063568,1050.46476]
       [217.210682,1050.47023]
       [271.123361,1050.47781]
       [324.675052,1050.48779]
       [377.692745,1050.50048]
       [427.845685,1053.07373]
       [461.323846,1068.71938]
       [494.723661,1084.33569]]
red_curve = [[0.0,1050.56801]
           [51.8993183,1050.56801]
           [103.798637,1050.56801]
           [155.697955,1050.56801]
           [207.597273,1050.56801]
           [259.496592,1050.56801]
           [311.39591,1050.56801]
           [363.295228,1050.56801]
           [415.191677,1050.56813]
           [455.961611,1065.59296]
           [495.02527,1083.69965]]

def unit_tangent_vector(curve):
tangent_vectors = np.diff(curve,axis=0)
unit_tangent_vectors = tangent_vectors / np.linalg.norm(tangent_vectors,axis=1)[:,None]
return unit_tangent_vectors

blue_curve_tangents = unit_tangent_vector(blue_curve)
blue_curve_tangents = np.vstack([blue_curve_tangents,blue_curve_tangents[-1]])
red_curve_tangents = unit_tangent_vector(red_curve)
red_curve_tangents = np.vstack([red_curve_tangents,red_curve_tangents[-1]])

n_dot_u = np.einsum('ij,ij->i',blue_curve_tangents,red_curve_tangents)
n_dot_a = np.einsum('ij,blue_curve)
n_dot_b = np.einsum('ij,red_curve)


intersections = red_curve + (n_dot_a[:,None]-n_dot_b[:,None])/(n_dot_u[:,None])*red_curve_tangents

任何关于我做错事情的想法吗?

谢谢

欢呼

解决方法

您的数学是正确的,检查正交性会得出:

bi = intersections - blue_curve
bb = np.diff(blue_curve,axis=0)
(bb[:-1] * bi).sum(axis=-1)
# array([ 0.,0.,0.])

我想问题是情节的缩放。 x axis来自[0,500],而y axis来自[1050.45,1050.56]。因此,您手工绘制的直角不正确,因为轴不在ratio 1:1中。实际上,交叉线稍微倾斜时,相交线似乎只是笔直向上。

例如,如果将x轴缩放1/1000倍,以使两个缩放更加相似,则生成的图像将按预期显示:


scale = 1 / 1000
red_curve[:,0] *= scale
blue_curve[:,0] *= scale

# .. your code

import matplotlib.pyplot as plt

fig,ax = plt.subplots()
ax.set_aspect(1)
ax.set_xlim(-2*scale,400*scale)
ax.set_ylim(1050.44,1050.58)
ax.plot(*blue_curve.T,'b',marker='o')
ax.plot(*red_curve.T,'r',marker='o')
ax.plot(*intersections.T,'k',ls='',marker='x')
for a,b in zip(blue_curve,intersections):
    ax.plot([a[0],b[0]],[a[1],b[1]],c='k')

line intersection