我认为这是一个相当基本的问题,我无法找到一个优雅的解决方案。想象一下,我在二维空间中有两条相当复杂的线(例如B样条),它们由两个维矩阵(n,2)跨越,其中n(行)是沿线的点数,两列分别对应于x和y坐标。更多信息:
我想找到这些线相交的点。就我的目的而言,将这两条线在每两个连续点之间线性化就足够了。
不幸的是,到目前为止我能提出的每个解决方案都是非常低效的(例如,使用两个嵌套的for循环并检查一行上的两个点的每个段与另一行上的每个段)。必须有一种更优雅的方式来做到这一点。
是否有任何类型的功能可以简化这种例程的实施?
P.S。:您可以在下面找到我上述系统的说明。
答案 0 :(得分:1)
感谢大家的回复,尤其是Dschoni相关的出版物参考,Piinthesky给出了解决方案的意见:
我们将两个线点的X坐标连接到一个公共向量,然后为两条线中的每一条插入Y坐标。因为我们现在在相同的X位置有点,我们可以相互减去Y值。在点之间,差异的符号发生变化,线相交。谢谢大家的帮助!
这是我的解决方案代码:
import pickle
import numpy as np
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt
# Load data series
X1 = pickle.load(open("X1.p","rb"))
Y1 = pickle.load(open("Y1.p","rb"))
X2 = pickle.load(open("X2.p","rb"))
Y2 = pickle.load(open("Y2.p","rb"))
# Convert X vectors to lists, and merge them
X1_list = list(X1)
X2_list = list(X2)
in_first = set(X1_list)
in_second = set(X2_list)
in_second_but_not_in_first = in_second - in_first
result = X1_list + list(in_second_but_not_in_first)
X_joint = np.asarray(result) # Revert to array
# Create interpolated functions
line_1 = interp1d(X1, Y1, kind='linear', fill_value='extrapolate')
line_2 = interp1d(X2, Y2, kind='linear', fill_value='extrapolate')
# Create joint Ys
Y1_joint = line_1(X_joint)
Y2_joint = line_2(X_joint)
# Calculate difference in Y
difference = Y1_joint-Y2_joint
# Plot the original data series
f, axarr = plt.subplots(2)
axarr[0].plot(X1, Y1,'b')
axarr[0].plot(X2, Y2,'r')
# Plot the difference values
axarr[1].plot(X_joint,difference)
axarr[1].plot([min(X_joint),max(X_joint)],[0,0],'k')
# The intersections are where the difference graph dips below or rises above zero
答案 1 :(得分:-1)
在两个给定数据点之间线性地插值每个函数f1,f2。使用不需要导数的方法最小化函数f = abs(f1-f2),但保持函数评估较低,例如Brent's method。该最小值的位置是您的近似交叉点。如果您不想自己实施该算法,请使用scipy.optimize.minimize_scalar
(docs)。