两点系列仅在延伸后相交?

时间:2013-11-10 11:15:28

标签: python algorithm numpy

我有两个点系列

A = [(18.405316791178798, -22.039859853332942),
 (18.372696520198463, -21.1145),
 (18.746540658574137, -20.1145),
 (18.698714698430614, -19.1145),
 (18.80081378263931, -18.1145),
 (18.838536172339943, -17.1145),
 (18.876258562040572, -16.1145),
 (18.967679510389303, -15.1145),
 (19.004907703822514, -14.1145),
 (19.042135897255729, -13.1145),
 (19.345372798084995, -12.1145),
 (19.391824245372803, -11.598937753853679),
 (19.435471418833544, -11.1145),
 (19.420235820376909, -10.1145),
 (19.423148861774159, -9.1145),
 (19.426061903171416, -8.1145),
 (19.452752569112423, -7.1145),
 (19.489649834463115, -6.1145),
 (19.444635952332344, -5.1145),
 (19.443635102001071, -5.0430597023976906),
 (19.430626347601358, -4.1145),
 (19.421676068414001, -3.1144999999999996),
 (19.362954522948439, -2.1144999999999996),
 (19.346848825989134, -1.1144999999999996),
 (19.359781116687397, -0.1144999999999996),
 (19.396797325132418, 0.69011368336827994)]

B=[(21.7744, -17.859620414326386),
 (22.7744, -17.858000854574556),
 (23.7744, -18.065164294951039),
 (24.7744, -18.051109497755608),
 (25.7744, -18.037054700560173),
 (26.7744, -18.022999903364742),
 (27.7744, -18.008945106169307),
 (28.7744, -18.014846881456318),
 (29.7744, -18.02764295838865),
 (30.7744, -18.098340990366935)]

我确定他们会相交,如果其中一个要从一个扩展

现在,我希望找到他们的“潜在”交集。我写了一个函数,可以找到“已经相交”的点系列的交点:

# find the intersection between two line segments
# if none, return None
# else, return sequence numbers in both rep1 and rep2 and the intersection
def _findIntersection(rep1, rep2):
    x_down = [elem[0] for elem in rep1]
    y_down = [elem[1] for elem in rep1]
    x_up = [elem[0] for elem in rep2]
    y_up = [elem[1] for elem in rep2]
    for m in xrange(len(x_down)-1):
        p0 = np.array([x_down[m], y_down[m]])
        p1 = np.array([x_down[m+1], y_down[m+1]])
        for n in xrange(len(x_up)-1):
            q0 = np.array([x_up[n], y_up[n]])
            q1 = np.array([x_up[n+1], y_up[n+1]])
            try: # to ignore the parallel cases
                params = np.linalg.solve(np.column_stack((p1-p0, q0-q1)), q0-p0)
                if np.all((params >= 0) & (params <= 1)):
                    return m, n, ((p0+params[0]*(p1-p0))[0], (p0+params[0]*(p1-p0))[1])
            except:
                pass

所以,我认为我需要的是找出需要扩展哪个点系列的哪一端。只要我知道这一点,我可以简单地扩展它并找到与现有的交集。 _findIntersection()

我们可以在这个问题中安全地假设两个点系列粗略两条直线,这意味着只存在一个交叉点。

我正在使用Python,但任何通用的解决方案也非常受欢迎!

2 个答案:

答案 0 :(得分:3)

我认为这样做的一种方法是找到两条线的功能然后使用这些功能,找到交叉点。以下是我将如何使用numpy(假设线条是线性的):

import numpy as np

def find_func(x,y):
    return np.polyfit(x, y, 1)

def find_intersect(funcA, funcB):
    a = funcA[0]-funcB[0]
    b = funcB[1]-funcA[1]
    x = b / a 
    assert np.around(find_y(funcA,x),3) == np.around(find_y(funcB,x),3)
    return x, find_y(funcA,x)

def find_y(func, x):
    return func[0] * x + func[1]


#find fits
func_A = find_func(A[:,1],A[:,0])
func_B = find_func(B[:,1],B[:,0])

#find intersection
x_intersect, y_intersect = find_intersect(func_A, func_B)

这是近似线性交点的绘制输出:

approximated intersection

答案 1 :(得分:2)

首先,获取每个点系列的回归线。通过将线的各个点序列的端点投影到线本身上,将线转换为线段s1和s2。

从线性代数的角度来看问题,两个线段是向量。除非它们是并行或共线,否则将每个向量乘以给定系数将使它们扩展到交叉点。因此,您需要找到系数alpha和beta,以便alpha * s1 = beta * s2。换句话说,求解线性方程alpha * s1 + beta * (-s1) = 0,就像您已经使用各个线段一样。

您需要注意三种情况。

  1. 如果alpha和beta的绝对值都小于或等于1,则交点位于两个线段内。
  2. 如果一个绝对值是&lt; = 1但是另一个是> 1,则交叉点i仅在两个线段中的一个(例如,s2)内。将该线段的矢量与刚刚获得的系数相乘,然后添加矢量的原点,以获得交点。然后,您可以确定另一个线段中的哪个端点(在这种情况下为s1)更接近交叉点;越接近一个是要延伸的那个。
  3. 如果两个绝对值都是> 1,只需通过将s1乘以(alpha / beta),然后将s1 [0]添加到该点来找到交点。找到交叉点后,只需在每个线段上找到与其最接近的端点。这些是必须扩展点系列的两个端点。