【问题标题】:Python - Find intersection between lines spanned by several pointsPython - 查找由多个点跨越的线之间的交点
【发布时间】:2018-01-16 00:24:33
【问题描述】:

我认为这是一个相当基本的问题,我找不到一个优雅的解决方案。想象一下,我在二维空间中有两条相当复杂的线(例如 B 样条),由两个维度矩阵 (n,2) 跨越,其中 n(行)是沿线的点数,两列分别对应x和y坐标。更多信息:

  • 两个连续点之间的距离相似,但不是恒定的。
  • 交点不一定是跨越线的点。
  • 可能存在(理论上)任意数量的交叉口

我想找到这些线相交的点。就我的目的而言,将每两个连续点之间的线视为线性就足够了。

不幸的是,到目前为止,我能想出的每个解决方案都非常低效(例如,使用两个嵌套的 for 循环并检查一条线上两点的每一段与另一条线上的每一段)。必须有一种更优雅的方式来做到这一点。

是否有任何类型的函数可以简化此类例程的实现?

P.S.:您可以在下面找到我上面描述的系统的插图。

【问题讨论】:

  • 你有一个连续的函数来创建这些行吗? x 点的距离和位置是否相同?
  • 如果上面的问题都不是,你可以用二叉树搜索来迭代。
  • 点之间的距离不是常数,但是一条曲线上的每个点[x, y1]在另一条曲线上都有一个等价点[x, y2]?
  • @Piinthesky 不幸的是,事实并非如此。但这给了我一个好主意:在每条线之间插入 x 以使其如此,然后将 y 值相互减去,然后识别符号变化的点!这实际上可能是解决方案......
  • folk.uio.no/martinre/Publications/intersection-preprint.pdf 这可能是一本好书。不过还是很棘手……

标签: python linear-algebra intersection


【解决方案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

【讨论】:

  • 仅供参考:只要两条样条线表示单射函数(或其离散表示),它就可以工作。它可能不适用于例如描述圆的样条曲线,因为 f(x) 不再不同。
【解决方案2】:

在两个给定数据点之间线性插值每个函数 f1、f2。使用不需要导数但保持函数评估较低的方法最小化函数 f = abs(f1 - f2),例如 Brent's method。该最小值的位置是您的近似交点。如果您不想自己实现算法,请使用scipy.optimize.minimize_scalar (docs)。

【讨论】:

  • 但是min(abs(f1-f2)) 返回曲线之间距离最小的点的 x 值,而不是两个最近点之间的交点。
  • 如问题中所述,行不必是函数。所以 (f1-f2) 可能并不明显。
  • 两个 cmets 都不适用于 f1、f2 在数据点之间线性插值...但我看到 J.Galt 想通了
  • @rerx 如果f 不是单射函数,我的评论确实适用。 OP中没有给出。
  • @Dschoni -- 是的,我没想到!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-24
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多