简体   繁体   English

两个函数的交点,多个x轴和y轴坐标

[英]Intersection points between two functions, multiple x-axis and y-axis coordinates

I'm working on a script which reads data from a MS Excel workbook and does some plotting etc. The data read from Excel are accelerations measurements in a_x , a_y , and a_z directions and the time in s (separate numpy arrays). I'm working on a script which reads data from a MS Excel workbook and does some plotting etc. The data read from Excel are accelerations measurements in a_x , a_y , and a_z directions and the time in s (separate numpy arrays). Accelerations are first filtered using a 5Hz low-pass filter before being plotted, see Figure 1 for a plot example, which are the permissible acceleration levels.在绘制之前,首先使用5Hz 低通滤波器对加速度进行滤波,参见图1中的 plot 示例,这是允许的加速度水平。

I need to find the amount of time the limiting curve is exceeded but the plot is related to a_z and abs(a_y) and not time.我需要找到超出限制曲线的时间量,但 plot 与a_zabs(a_y)相关,而不是时间。 My attempted solution is to:我尝试的解决方案是:

  1. Find the intersection points between the acceleration and the limiting curve.找到加速度和极限曲线之间的交点。
  2. Find the data points ( a_z and abs(a_y) ) closest to the intersection point.找到最接近交点的数据点( a_zabs(a_y) )。
  3. Get the indices for data points closest to the intersection points.获取最接近交点的数据点的索引。
  4. Use the found indices for the time array and substract the two to get the amount of time above limiting curves.使用时间数组找到的索引并减去两者以获得超过限制曲线的时间量。

The problem is I fail a bullet 3. I've succeeded in finding intersection points between the limiting curve and my filtered data.问题是我没有通过第 3 个项目符号。我成功地找到了限制曲线和过滤数据之间的交点。 I've also managed in to find my data points nearest the intersection points however, if I found the closest intersection point for a_z this doesn't match the index I get from abs(a_y) .我还设法找到最接近交点的数据点,但是,如果我找到a_z的最近交点,这与我从abs(a_y)获得的索引不匹配。

Intersection points are found by:交点通过以下方式找到:

f_l1 = LineString(np.column_stack((x, y1)))
s_l1 = LineString(np.column_stack((az3, abs(ay3))))
intersection1 = f_l1.intersection(s_l1)
az3_1,ay3_1 = LineString(intersection1).xy

So I'm using shapely.geometry imported as LineString to find the intersection points between the limiting curves (here shown for limiting curve y1) and the function s_l1(az,abs(a_y)).因此,我使用作为 LineString 导入的 shapely.geometry 来查找限制曲线(此处显示为限制曲线 y1)和 function s_l1(az,abs(a_y)) 之间的交点。

To find the my data points closest to the intersection points I used the following approach:为了找到最接近交叉点的数据点,我使用了以下方法:

Intersection of two graphs in Python, find the x value Python中两个图的交集,求x值

The function I use to get my data point closest to the intersection point is:我用来获取最接近交点的数据点的 function 是:

def find_nearest_index(array, value):
    array = np.asarray(array)
    idx = np.abs(abs(array-value)).argmin()
    return idx

, where the array is my filtered acceleration array and the value is either the a_z or a_y value of the intersection point. ,其中数组是我的过滤加速度数组,值是交点的a_za_y值。

I suspect the reason for different indices depending on a_z or abs(a_y) is because my data points are "too far" from the actual intersection coordinate, ie I might get a a_z coordinate, which value is close to the intersection point but the corresponding abs(a_y) is way off.我怀疑取决于a_zabs(a_y)的不同索引的原因是因为我的数据点与实际的交叉点坐标“太远”,即我可能会得到一个a_z坐标,该值接近交叉点但对应的abs(a_y)很遥远。 Similar issue is present for the abs(a_y) intersection point/data-point correlation. abs(a_y)交叉点/数据点相关性也存在类似问题。 For upcoming measurements, I'll increase the sampling frequency but I doubt this will solve the matter completely.对于即将到来的测量,我会增加采样频率,但我怀疑这会完全解决问题。

I've attempted some different approaches without much luck and my latest idea is to try to use both intersection points when locating the nearest data point, so I check if the index I get from my find_nearest_index-function using a_z is the same as the index I get from using find_nearest_index-function for abs(a_y) but I don't know how/if that is possible.我尝试了一些不同的方法,但没有太多运气,我的最新想法是在定位最近的数据点时尝试使用两个交点,所以我检查我使用a_z从我的 find_nearest_index 函数获得的索引是否与索引相同我从对abs(a_y)使用 find_nearest_index-function 得到,但我不知道如何/是否可能。 But maybe there's an obvious solution to my problem that I just don't see.但也许对我的问题有一个明显的解决方案,我只是没有看到。

A correct solution for the accelerations would like the following, where the index of my data points match the intersection points: Desirable plot between intersection points These indices are then used for calculating the amount of time above the limiting curve by taking Delta_t=t[index2]-t[index1].加速度的正确解决方案如下所示,其中我的数据点的索引与交叉点匹配: 交叉点之间的理想 plot然后这些索引用于计算超出限制曲线的时间量,方法是采用 Delta_t=t[index2 ]-t[索引1]。

But instead I typically get something like, where the index found by using a_z is different from the index found using a_y) resulting in a wrong plot and therefore also wrong Delta_t: Typical plot between intersection points但是相反,我通常会得到类似的结果,其中使用 a_z 找到的索引与使用a_z找到的索引不同a_y)导致错误的 plot 并因此也错误 Delta_t:交点之间的典型 plot

I hope you guys can help me and thanks for reading this far.我希望你们能帮助我,并感谢您阅读本文。

Best regards,此致,

Mikael迈凯尔

This is my approach to re-use the idea of np.diff()这是我重用np.diff()想法的方法


import matplotlib.pyplot as plt
import numpy as np


### this is somewhat one of the bounds given in the OP
pathx = np.array([
    -1.7,
    -1.5, -0.5,
    0, 
    1.75, 5.4,
    6
])

pathy = np.array([
    0,
    0.75, 2.25,
    2.45,
    2.2, 0.75, 0
])

path = np.column_stack( ( pathx, pathy ) )

### this creates a random path
def rand_path( n ):
    vy = 0.04
    vx = 0
    xl = [0]
    yl = [0]
    for i in range( n ):
        phi = (1-1.6 *np.random.random() ) * 0.1
        mx = np.array( [[np.cos(phi), np.sin( phi )],[-np.sin(phi), np.cos(phi)]] )
        v = np.dot( mx, np.array( [vx, vy]) )
        vx = v[0]
        vy = v[1]
        x = xl[-1] + vx
        y = yl[-1] + vy
        xl = xl + [x]
        yl = yl + [y]
    return xl, np.abs( yl )

### my version tocheck inside or not
def check_inside( point, path ):
    """
    check if point is inside convex boundary
    """
    out = 1
    for p2, p1 in zip( path[ 1: ], path[ :-1 ] ):
        q = p2 - p1
        Q = point - p1
        cross = q[0] * Q[1] - q[1] * Q[0]
        if cross > 0:
            out = 0
            break
    return out

### test data
xl ,yl = rand_path(1200)
data = np.column_stack( ( xl, yl ) )
##check and use np.diff like in the other example 
# ~ cp = np.array( [ check_inside( p, path) for p in data] )
cp = np.fromiter( ( check_inside( p, path) for p in data), int )
ip = np.argwhere( np.diff( cp ) )

### get the points
if len( ip):
    ip = np.concatenate( ip )
pnts = data[ ip ]

"""
We could additionally use the cp information to ckeck if we are passing
inward or outward, to shift the point index by one and by doing so only
getting data outside
In a next step we could get the true intersection and the data
outside or inside of  bounding regions.
"""
### plot
fig = plt.figure()

ax = fig.add_subplot( 1, 1, 1)
ax.scatter( pnts[:,0], pnts[:,1])

ax.plot( path[:,0], path[:,1])
ax.plot( xl, yl)

ax.grid()
plt.show()

测试运行

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM