如何生成等距内插值 [英] How to generate equispaced interpolating values

查看:190
本文介绍了如何生成等距内插值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个(x,y)值的列表,这些值不是均匀间隔的. 此处是此问题中使用的存档.

I have a list of (x,y) values that are not uniformly spaced. Here is the archive used in this question.

我可以在值之间进行插值,但是得到的不是等距插值点.这是我的工作:

I am able to interpolate between the values but what I get are not equispaced interpolating points. Here's what I do:

x_data = [0.613,0.615,0.615,...]
y_data = [5.919,5.349,5.413,...]

# Interpolate values for x and y.
t = np.linspace(0, 1, len(x_data))
t2 = np.linspace(0, 1, 100)
# One-dimensional linear interpolation.
x2 = np.interp(t2, t, x_data)
y2 = np.interp(t2, t, y_data)

# Plot x,y data.
plt.scatter(x_data, y_data, marker='o', color='k', s=40, lw=0.)

# Plot interpolated points.
plt.scatter(x2, y2, marker='o', color='r', s=10, lw=0.5)

这将导致:

可以看出,在图中原始点分布较密集的部分中,红点靠得更近.

As can be seen, the red dots are closer together in sections of the graph where the original points distribution is denser.

我需要一种方法,根据给定的步长值(例如0.1)在x,y中生成等距的内插点

I need a way to generate the interpolated points equispaced in x, y according to a given step value (say 0.1)

正如 askewchan 正确指出的那样,当我在x,y中表示"等距"时,我的意思是曲线中两个连续的插值点应彼此隔开(欧氏直线距离)相同的值.

As askewchan correctly points out, when I mean "equispaced in x, y" I mean that two consecutive interpolated points in the curve should be distanced from each other (euclidean straight line distance) by the same value.

我尝试了unubtu的答案,它对于平滑曲线效果很好,但对于不那么平滑的曲线似乎会折断:

I tried unubtu's answer and it works well for smooth curves but seems to break for not so smooth ones:

之所以会发生这种情况,是因为代码以欧几里德的方式计算了点的距离,而不是直接在曲线上,并且我需要曲线上的距离在点之间相同.可以以某种方式解决此问题吗?

This happens because the code calculates the point distance in an euclidean way instead of directly over the curve and I need the distance over the curve to be the same between points. Can this issue be worked around somehow?

推荐答案

让我们首先考虑一个简单的情况.假设您的数据看起来像蓝线, 以下.

Let's first consider a simple case. Suppose your data looked like the blue line, below.

如果您要选择相距距离r的等距点, 那么r会有一个临界值,其中(1,2)的尖点是第一个等距点.

If you wanted to select equidistant points that were r distance apart, then there would be some critical value for r where the cusp at (1,2) is the first equidistant point.

如果您想要的点比该临界距离大 ,则 第一个等距点将从(1,2)跳到一个非常不同的地方- 用绿色弧线和蓝色线的交点表示.这种变化不是渐进的.

If you wanted points that were greater than this critical distance apart, then the first equidistant point would jump from (1,2) to some place very different -- depicted by the intersection of the green arc with the blue line. The change is not gradual.

这个玩具案表明,参数r的微小变化会对解决方案产生根本性的,不连续的影响.

This toy case suggests that a tiny change in the parameter r can have a radical, discontinuous affect on the solution.

它还建议您必须知道第i个等距点的位置 在确定第(i + 1)个等距点的位置之前.

It also suggests that you must know the location of the ith equidistant point before you can determine the location of the (i+1)-th equidistant point.

因此似乎需要迭代解决方案:

So it appears an iterative solution is required:

import numpy as np
import matplotlib.pyplot as plt
import math

x, y = np.genfromtxt('data', unpack=True, skip_header=1)
# find lots of points on the piecewise linear curve defined by x and y
M = 1000
t = np.linspace(0, len(x), M)
x = np.interp(t, np.arange(len(x)), x)
y = np.interp(t, np.arange(len(y)), y)
tol = 1.5
i, idx = 0, [0]
while i < len(x):
    total_dist = 0
    for j in range(i+1, len(x)):
        total_dist += math.sqrt((x[j]-x[j-1])**2 + (y[j]-y[j-1])**2)
        if total_dist > tol:
            idx.append(j)
            break
    i = j+1

xn = x[idx]
yn = y[idx]
fig, ax = plt.subplots()
ax.plot(x, y, '-')
ax.scatter(xn, yn, s=50)
ax.set_aspect('equal')
plt.show()

注意:我将纵横比设置为'equal',以使点之间的等距更加明显.

Note: I set the aspect ratio to 'equal' to make it more apparent that the points are equidistant.

这篇关于如何生成等距内插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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