如何在Python中找到一条线与多条曲线的交点? [英] How to find the points of intersection of a line and multiple curves in Python?

查看:1227
本文介绍了如何在Python中找到一条线与多条曲线的交点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有图中表示的数据.

曲线是外推的,我有一条方程式已知的直线.曲线方程未知.现在,如何找到这条线与每条曲线的交点?

The curves were extrapolated and I have a line whose equation is known. The equation of curves are unknown. Now, how do I find the points of intersection of this line with each of the curves?

可复制的代码:

import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate


x = np.array([[0.12, 0.11, 0.1, 0.09, 0.08],
              [0.13, 0.12, 0.11, 0.1, 0.09],
              [0.15, 0.14, 0.12, 0.11, 0.1],
              [0.17, 0.15, 0.14, 0.12, 0.11],
              [0.19, 0.17, 0.16, 0.14, 0.12],
              [0.22, 0.19, 0.17, 0.15, 0.13],
              [0.24, 0.22, 0.19, 0.16, 0.14],
              [0.27, 0.24, 0.21, 0.18, 0.15],
              [0.29, 0.26, 0.22, 0.19, 0.16]])

y = np.array([[71.64, 78.52, 84.91, 89.35, 97.58],
              [66.28, 73.67, 79.87, 85.36, 93.24],
              [61.48, 69.31, 75.36, 81.87, 89.35],
              [57.61, 65.75, 71.7, 79.1, 86.13],
              [55.12, 63.34, 69.32, 77.29, 83.88],
              [54.58, 62.54, 68.7, 76.72, 82.92],
              [56.58, 63.87, 70.3, 77.69, 83.53],
              [61.67, 67.79, 74.41, 80.43, 85.86],
              [70.08, 74.62, 80.93, 85.06, 89.84]])


x1 = np.linspace(0, 0.4, 100)
y1 = -100 * x1 + 100
plt.figure(figsize = (5.15,5.15))
plt.subplot(111)
for i in range(5):
    x_val = np.linspace(x[0, i] - 0.05, x[-1, i] + 0.05, 100)
    x_int = np.interp(x_val, x[:, i], y[:, i])
    poly = np.polyfit(x[:, i], y[:, i], deg=2)
    y_int  = np.polyval(poly, x_val)
    plt.plot(x[:, i], y[:, i], linestyle = '', marker = 'o')
    plt.plot(x_val, y_int, linestyle = ':', linewidth = 0.25, color =  'black')
plt.plot(x1, y1, linestyle = '-.', linewidth = 0.5, color =  'black')


plt.xlabel('X')
plt.ylabel('Y')
plt.show()

推荐答案

我们知道.它们的格式为a*x**2 + b*x + c,其中abcnp.polyfit返回的向量的元素.然后,我们只需要找到二次方程的根即可找到交点:

We do know the equations of the curves. They are of the form a*x**2 + b*x + c, where a,b, and c are the elements of the vector returned by np.polyfit. Then we just need to find the roots of a quadratic equation in order to find the intersections:

def quadratic_intersections(p, q):
    """Given two quadratics p and q, determines the points of intersection"""
    x = np.roots(np.asarray(p) - np.asarray(q))
    y = np.polyval(p, x)
    return x, y

上面的函数并不是超级健壮:不需要是真实的根,并且也没有真正检查它.您可以自由地做得更好.

The above function isn't super robust: there doesn't need to be a real root, and it doesn't really check for that. You're free to make it better.

无论如何,我们给quadratic_intersections两个二次方,它返回相交的两个点.将其放入您的代码中,我们可以:

Anyways, we give quadratic_intersections two quadratics, and it returns the two points of intersection. Putting it into your code, we have:

x1 = np.linspace(0, 0.4, 100)
y1 = -100 * x1 + 100
plt.figure(figsize = (7,7))
plt.subplot(111)

plt.plot(x1, y1, linestyle = '-.', linewidth = 0.5, color =  'black')
for i in range(5):
    x_val = np.linspace(x[0, i] - 0.05, x[-1, i] + 0.05, 100)
    poly = np.polyfit(x[:, i], y[:, i], deg=2)
    y_int  = np.polyval(poly, x_val)
    plt.plot(x[:, i], y[:, i], linestyle = '', marker = 'o')
    plt.plot(x_val, y_int, linestyle = ':', linewidth = 0.25, color =  'black')
    ix = quadratic_intersections(poly, [0, -100, 100])
    plt.scatter(*ix, marker='x', color='black', s=40, linewidth=2)

plt.xlabel('X')
plt.ylabel('Y')
plt.xlim([0,.35])
plt.ylim([40,110])
plt.show()

如下图所示:

现在,如果您不知道要处理的函数是多项式,则可以使用

Now, if you don't know that the functions you are dealing with are polynomials, you can use the optimization tools in scipy.optimize to find the root. For example:

import scipy.optimize
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.style

matplotlib.style.use('fivethirtyeight')
%matplotlib inline

f = lambda x: np.cos(x) - x
g = np.sin

h = lambda x: f(x) - g(x)

x = np.linspace(0,3,100)
plt.plot(x, f(x), zorder=1)
plt.plot(x, g(x), zorder=1)

x_int = scipy.optimize.fsolve(h, 1.0)
y_int = f(x_int)

plt.scatter(x_int, y_int, marker='x', s=150, zorder=2, 
            linewidth=2, color='black')

plt.xlim([0,3])
plt.ylim([-4,2])

哪些情节:

这篇关于如何在Python中找到一条线与多条曲线的交点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆