平面线交点

Plane line intersection

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

所以我想解决这个问题的方法是找到每个红点之间的线与蓝线每个点的切向量形成的平面相交的点:

问题是,当我尝试为列表中的每个点求解 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,ij->i', blue_curve_tangents,blue_curve)
n_dot_b = np.einsum('ij,ij->i', blue_curve_tangents,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., 0., 0., 0., 0., 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')