This is a perfect solution by no means. It aims to give you some ideas of how it can be done since there is no more data.
The major problem you are trying to solve is to deal with two piece-wise straight lines. And the pieces do not align. An obvious solution is to interpolate both and obtain a union of x's. Then the calculation of distances is easier.
import numpy as np
import matplotlib.pyplot as plt
# Toy data
x1 = [0, 1, 2, 3, 4, 5, 6]
y1 = [9, 8, 9, 10, 7, 6, 9]
x2 = [0.5, 3, 5, 6, 9]
y2 = [0, 1, 3, 2, 1]
# Interpolation for both lines
points1 = list(zip(x1, y1))
y1_interp = np.interp(x2, x1, y1)
interp_points1 = list(zip(x2, y1_interp))
l1 = list(set(points1 + interp_points1))
all_points1 = sorted(l1, key = lambda x: x[0])
points2 = list(zip(x2, y2))
y2_interp = np.interp(x1, x2, y2)
interp_points2 = list(zip(x1, y2_interp))
l2 = list(set(points2 + interp_points2))
all_points2 = sorted(l2, key = lambda x: x[0])
assert(len(all_points1) == len(all_points2))
# Since I do not have data points on the blue line,
# I will calculate the average distance based on x's of all interpolated points
sum_d = 0
for i in range(len(all_points1)):
sum_d += all_points1[i][1] - all_points2[i][1]
avg_d = sum_d / len(all_points1)
threshold = 0.5
d_threshold = avg_d * threshold
for i in range(len(all_points1)):
d = all_points1[i][1] - all_points2[i][1]
if d / avg_d < threshold:
print("Distance below threshold between", all_points1[i], "and", all_points2[i])
Notice that np.interp
extrapolate values as well, but they do not participate in the calculation.
Now there is a remaining question: if you actually need to know when the distance falls below threshold other than the interpolated points only, one needs to analytically search for the first and last points in each piece of lines. Here is a piece of sample:
for i in range(len(all_points1) - 1):
(pre_x1, pre_y1) = all_points1[i]
(post_x1, post_y1) = all_points1[i + 1]
(pre_x2, pre_y2) = all_points2[i]
(post_x2, post_y2) = all_points2[i + 1]
# Skip the pieces that will never have qualified points
if (pre_y1 - pre_y2) / avg_d >= threshold and (post_y1 - post_y2) / avg_d >= threshold:
continue
k1 = (post_y1 - pre_y1) / (post_x1 - pre_x1)
b1 = (post_x1 * pre_y1 - pre_x1 * post_y1) / (post_x1 - pre_x1)
k2 = (post_y2 - pre_y2) / (post_x2 - pre_x2)
b2 = (post_x2 * pre_y2 - pre_x2 * post_y2) / (post_x2 - pre_x2)
x_start = (d_threshold - b1 + b2) / (k1 - k2)
print("The first point where the distance falls below threshold is at x=", x_start)
break