我有一组近似于2D曲线的点,我想使用Python和numpy、scipy来找到一条近似拟合这些点的三次贝塞尔曲线,其中我指定了两个端点的精确坐标,它将返回另外两个控制点的坐标。
我最初认为scipy.interpolate.splprep()
可以满足我的要求,但它似乎迫使曲线通过每个数据点(我想您会希望进行插值)。
我的问题和这一个相似:How can I fit a Bézier curve to a set of data?,只是他们说不想使用numpy。我的偏好是在scipy或numpy中找到我需要的已经实现的东西。否则,我计划使用numpy实现与该问题的答案之一链接的算法:An algorithm for automatically fitting digitized curves(pdf第622页)。
谢谢您的建议!
编辑:我理解一条三次贝塞尔曲线并不能保证通过所有的点;我想要一个通过两个给定的端点,并尽可能接近指定的内部点。
8条答案
按热度按时间6vl6ewon1#
以下是使用numpy创建Bezier曲线的方法:
zwghvu4y2#
下面是一段用于拟合点的python代码:
一般在贝塞尔曲线上检查出Animated bezier和bezierinfo
u7up0aaq3#
@keynesiancross要求“对[罗兰的]代码中的变量进行注解”,而其他人则完全忽略了这个问题。(以获得完美匹配),这使得我们更难理解这个问题(至少对我来说)的解决方案。与插值的区别是更容易看到的输入,留下残差。这里既有释义的代码和非贝兹输入--和一个意想不到的结果。
这对
fcn = np.cos
很有效,但对log
就不行了。我希望拟合会使用控制点的t分量作为额外的自由度,就像我们通过拖动控制点所做的那样:我想,失败的原因是范数测量的是曲线上的点之间的距离,而不是一条曲线上的点到另一条曲线上最近的点之间的距离。
5lhxktic4#
Resulting Plot
根据@reptilicus和@Guillaume P.的回答,以下是完整的代码:
获取贝塞尔参数,即从一组X、Y点或坐标中获取控制点。所需的另一个参数是近似度,生成的控制点将为(度+1)
根据给定的Bezier参数(即控制点)创建Bezier曲线。
使用的样本数据(可替换为任何数据,这是GPS数据)。
绘制原始点、控制点和生成的贝塞尔曲线。
m528fe3b5#
简短回答:你不需要,因为贝塞尔曲线不是这样工作的。更长的答案是:看一下Catmull-Rom样条。它们非常容易形成(除起点和终点外,任意点P处的切向量都平行于直线{P-1,P+1},因此它们也很容易编程),并且总是通过定义它们的点,不像Bezier曲线,它在所有控制点建立的船体内的“某个地方”插值。
sr4lhrrt6#
Bezier曲线不能保证通过您提供给它的每个点;控制点是任意的(从没有特定的算法来找到它们的意义上说,你只是自己选择它们),并且只在一个方向上 * 拉 * 曲线。
如果你想要一条曲线通过你提供给它的每一个点,你需要像自然三次样条曲线这样的东西,由于这些曲线的限制(你必须提供递增的x坐标,否则它会趋向无穷大),你可能会需要一个参数化的自然三次样条曲线。
这里有一些不错的教程:
Cubic Splines
Parametric Cubic Splines
7y4bm7vi7#
我遇到了和问题中详细描述的一样的问题。我使用了罗兰Puntayer提供的代码,并能够使它工作。这里:
要固定曲线的端点,请忽略函数返回的第一个和最后一个参数,并使用您自己的点。
xxe27gdn8#
Mike Kamermans说的是真的,但我也想指出,据我所知,catmull-rom样条可以用三次贝塞尔曲线来定义。因此,如果你只有一个处理三次贝塞尔曲线的库,你应该仍然能够处理catmull-rom样条: