【问题标题】:Finding the intersection point between line and piecewise linear curves查找直线和分段线性曲线之间的交点
【发布时间】:2017-08-18 09:01:35
【问题描述】:

我有两条曲线,一条是一条线,例如 y = x/4,另一条是我用线段连接的一组点(例如:x = [1, 2.5, 3.4, 5.8, 6]y = [2, 4, 5.8, 4.3, 4],它们在形成分段线性曲线的二维平面),我应该找到这两条曲线之间的交点。我应该首先形成这条分段线性曲线,然后找到交点。幸运的是,我发现我可以使用numpy.polyfit 找到每个线段的多项式系数,如下所示:

import numpy as np
import matplotlib.pyplot as plt
x = [0, 1, 2, 4, 6]  # in my primary problem i dont have just 5 points and i have approximately 200 points !
y = [0, 0, 3, -1, 2]
x = np.array(x)
y = np.array(y)
a = [np.polyfit(x[i:(i+2)], y[i:(i+2)], 1) for i in range(len(x)-1)]
plt.plot(x, y, 'o')
plt.show()

但是现在我真的很困惑如何使用这些系数来找到两个图之间的交点!? (在我的主要问题中,我不只有 5 分,我有大约 200 分!) 解决这个问题的一个想法是使用 ((solve)) 命令检查线和线段的交点,但这非常耗时,并且此命令不适用于线((segment))。

【问题讨论】:

    标签: python numpy curve


    【解决方案1】:

    没有理由应该只有一个交点。对于您的示例,如果您采用 $y = 1$,您将有三个十字路口,如果您采用 $y = -2$,您将没有,如果您采用 $y = 0$,您将有无限很多。

    要找到它们,一种方法是考虑连接xy 中的元素的每个线段,并且您已经找到了它们的斜率和相交,并将线段扩展到在实线上定义。现在,例如使用the procedures in this question 之一找到给定线和扩展线之间的交点。如果有 0 个交点,则原始未延伸线段也有 0 个交点,如果有 1 个交点,如果 x 值位于定义线段的 x 值范围内(且 0否则),如果有无限多个交点,则线段上的每个点都将位于交点中。对每个线段重复该过程。

    def get_intersection(line1, line2):
        """Returns the intersection, if any, between two lines, None if the lines are equal, and
        the empty array if the lines are parallel.
    
        Args:
            line1 (numpy.array): [slope, intercept] of the first line.
            line2 (numpy.array): [slope, intercept] of the second line.
    
        Taken from https://stackoverflow.com/a/42727584/5085211.
        """
        if (np.array_equal(line1, line2)):
            return None
        if line1[0] == line2[0]:
            return np.empty(0)
        l1 = np.insert(line1, 1, -1)
        l2 = np.insert(line2, 1, -1)
        x, y, z = np.cross(l1, l2)
        return np.hstack([x, y]) / z
    
    line_of_interest = [0.25, 0]  # y = x/4
    
    for i in range(len(x)-1):
        p = get_intersection(a[i], line_of_interest)
        if np.array_equal(p, []):
            continue
        elif np.array_equal(p, None):
            print('Entire line segment between {0} and {1}'.format(x[i], x[i+1]))
        elif x[i] <= p[0] and p[0] < x[i+1]:
            print(p)
    
    # Prints:
    # [ 0.  0.]
    # [ 1.09090909  0.27272727]
    # [ 3.11111111  0.77777778]
    # [ 5.6  1.4]
    

    【讨论】:

    • 谢谢。在我的问题中,我当然没有这样的行 (y = 0 or y = (a number)) 。真的,我有一条与初始线段具有相同斜率的线!事实上,我应该从应变-应力曲线中找到屈服偏移应力,该曲线的定义是该线应与应变-应力曲线平行,但偏移量为 0.002。 . . (你可以在谷歌中通过非常简单的搜索看到这个定义!例如click here!)。 . .我想要那个屈服抵消应力,我所做的就是找到那个。
    • 所以您似乎在说的是,您的分段线性函数在定义它的所有点处都随着斜率小于或等于给定线的斜率而单调增加;这使得这个问题在数值上比 OP 中的一般问题更容易解决,但如果你只想为 200 个线段的集合做这个,上面的方法就可以了。
    • 我不能说所有的线段都有一个单调递增的斜率!例如click here 看到这个典型的应力-应变曲线,它几乎有 6 个区域具有不同的斜率趋势!(我的应力-应变曲线也与这个相似!而且我的斜率也有这种变化!)我只有还有两个问题:因为我对编程很陌生,你能说一下你的代码是如何工作的吗?这对我的应力-应变曲线是否正常工作?谢谢
    • 答案中的解决方案不假设任何单调性。
    • 非常感谢,我真的会使用这个代码,但现在我有一个想法,你能把这个和上面的代码比较一下吗?如果我将每条线段视为一条线,然后我编写一个循环来检查 y = x/4 和每个线段之间的交点,然后当第一条线段与 y = x/4 内部的交点的 x 坐标线段的 x 投影,我可以得出结论,这个交点是我的压力?(在我的想法中,我只需要找到两条线之间的交点,而不是线段和一条线!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多