1
votes

I am struggling finding a solution to code a problem in python. I have these red and blue curves (which are just list of points in python). And I want to find the purple points on the red line. enter image description here

So I thought a solution to this problem was to find the points that intersects the line between each red points and the plane formed by the tangent vector at each point of the blue line: enter image description here

The problem is when I try to solve this simple equation in python for each of the points of the lists, I end up finding the green points which are incorrectly placed. Here is my code:

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

Any idea of what I am doing wrong ?

Thanks

Cheers

1

1 Answers

1
votes

Your math is correct, checking the orthogonality gives:

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.])

I guess the problem is the scaling of your plot. The x axis goes from [0, 500] and the y axis goes from [1050.45, 1050.56]. So the right angles you have drawn by hand aren't correct as the axes aren't in a ratio 1:1. The intersection lines seem to just got straight up when in reality the have are slightly angled.

If you scale for example the x axis by a factor 1/1000 to make the two scales more similar the resulting image looks as expected:


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