我有一组点 pts
形成一个循环,它看起来像这样:
这有点类似于31243002,但是我不想在点对之间放置点,而是想在点之间插入一条平滑的曲线(坐标在问题的末尾给出),所以我尝试了类似于 scipy
文档的东西 . Interpolation:
values = pts
tck = interpolate.splrep(values[:,0], values[:,1], s=1)
xnew = np.arange(2,7,0.01)
ynew = interpolate.splev(xnew, tck, der=0)
但我得到这个错误:
ValueError:输入数据错误
有没有办法找到这样的合适?
点数的坐标:
pts = array([[ 6.55525 , 3.05472 ],
[ 6.17284 , 2.802609],
[ 5.53946 , 2.649209],
[ 4.93053 , 2.444444],
[ 4.32544 , 2.318749],
[ 3.90982 , 2.2875 ],
[ 3.51294 , 2.221875],
[ 3.09107 , 2.29375 ],
[ 2.64013 , 2.4375 ],
[ 2.275444, 2.653124],
[ 2.137945, 3.26562 ],
[ 2.15982 , 3.84375 ],
[ 2.20982 , 4.31562 ],
[ 2.334704, 4.87873 ],
[ 2.314264, 5.5047 ],
[ 2.311709, 5.9135 ],
[ 2.29638 , 6.42961 ],
[ 2.619374, 6.75021 ],
[ 3.32448 , 6.66353 ],
[ 3.31582 , 5.68866 ],
[ 3.35159 , 5.17255 ],
[ 3.48482 , 4.73125 ],
[ 3.70669 , 4.51875 ],
[ 4.23639 , 4.58968 ],
[ 4.39592 , 4.94615 ],
[ 4.33527 , 5.33862 ],
[ 3.95968 , 5.61967 ],
[ 3.56366 , 5.73976 ],
[ 3.78818 , 6.55292 ],
[ 4.27712 , 6.8283 ],
[ 4.89532 , 6.78615 ],
[ 5.35334 , 6.72433 ],
[ 5.71583 , 6.54449 ],
[ 6.13452 , 6.46019 ],
[ 6.54478 , 6.26068 ],
[ 6.7873 , 5.74615 ],
[ 6.64086 , 5.25269 ],
[ 6.45649 , 4.86206 ],
[ 6.41586 , 4.46519 ],
[ 5.44711 , 4.26519 ],
[ 5.04087 , 4.10581 ],
[ 4.70013 , 3.67405 ],
[ 4.83482 , 3.4375 ],
[ 5.34086 , 3.43394 ],
[ 5.76392 , 3.55156 ],
[ 6.37056 , 3.8778 ],
[ 6.53116 , 3.47228 ]])
4 回答
要通过N个点拟合平滑的闭合曲线,您可以使用具有以下约束的线段:
每个线段必须触及其两个 endpoints (每个线段2个条件)
对于每个点,左右线段必须具有相同的导数(每个点2个条件=每个线段2个条件)
为了能够在每个线段的总共4个条件中具有足够的自由度,每个线段的等式应该是y = ax ^ 3 bx ^ 2 cx d . (因此导数是y'= 3ax ^ 2 2bx c)
如上所述设置条件将为N * 4个未知数(a1..aN,b1..bN,c1..cN,d1..dN)提供N * 4个线性方程,可通过矩阵求逆(numpy)求解 .
如果点在同一垂直线上,则需要特殊(但简单)处理,因为导数将是“无限” .
使用ROOT Framework和pyroot接口,我能够生成以下图像
使用以下代码(我将您的数据转换为名为data.csv的CSV,因此将其读入ROOT会更容易,并给出了xp,yp的列 Headers )
实际上,你离问题的解决方案并不遥远 .
使用scipy.interpolate.splprep进行参数化B样条插值将是最简单的方法 . 如果您提供
per=1
参数,它本身也支持闭合曲线,从根本上说,这种方法与@Joe Kington的回答没有什么不同 . 虽然,它可能会更加健壮,因为默认情况下,基于点之间的距离而不仅仅是它们的索引,选择等效的
i
向量(参见splprep documentation参数的splprep documentation) .您的问题是因为您重新调用假定x值按排序顺序并且每个
x
值将具有唯一的y值 .相反,您需要创建一个参数化坐标系(例如顶点的索引)并使用它分别插入x和y .
首先,请考虑以下事项:
我没有't close the polygon. If you'喜欢,你可以将第一个点添加到数组的末尾(例如
pts = np.vstack([pts, pts[0]])
如果你这样做,你会注意到多边形关闭时存在不连续性 .
这是因为我们的参数化没有考虑关闭polgyon . 快速解决方法是使用“反射”点填充数组:
或者,您可以使用专门的曲线平滑算法,如PEAK或切角算法 .