问题描述
我有一个不均匀间隔的 (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, thenthe 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 pointbefore 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.
这篇关于如何生成等距插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!