我有一组近似于2D曲线的点 . 我想使用带有numpy和scipy的Python来找到一个大致适合点的三次Bézier路径,其中我指定了两个 endpoints 的精确坐标,并返回其他两个控制点的坐标 .
我最初认为 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.page 622) .
谢谢你的任何建议!
编辑:据我所知,立方Bézier曲线无法保证通过所有点;我想要一个通过两个给定 endpoints ,并且尽可能接近指定内部点的 endpoints .
6 回答
这是一段用于拟合点的python代码:
通常在贝塞尔曲线上查看Animated bezier和bezierinfo
这是一种用numpy做Bezier曲线的方法:
贝塞尔曲线不能保证通过您提供的每个点;控制点是任意的(在某种意义上说,没有特定的算法可以找到它们,你只需自己选择它们)并且只在一个方向上拉动曲线 .
如果你想要一条能够通过你提供的每一个点的曲线,你需要像天然三次样条这样的东西,并且由于它们的局限性(你必须为它们提供增加的x坐标,或者它倾向于无穷大) ,你可能想要一个参数化的自然三次样条 .
这里有很好的教程:
Cubic Splines
Parametric Cubic Splines
简短的回答:你没有,因为这不是Bezier曲线的工作方式 . 更长的答案:看看Catmull-Rom splines . 它们很容易形成(任何点P处的切向量,禁止开始和结束,与线{P-1,P 1}平行,所以它们也很容易编程)并且总是通过定义它们的点,与贝塞尔曲线不同,贝塞尔曲线在所有控制点设置的凸包内插入“某处” .
Mike Kamermans所说的是真的,但我也想指出,据我所知,catmull-rom样条可以用立方贝塞尔数来定义 . 因此,如果您只有一个可以使用Cubic的库,那么您仍然可以使用catmull-rom样条:
http://schepers.cc/getting-to-the-point
https://github.com/DmitryBaranovskiy/raphael/blob/master/dev/raphael.core.js#L1038
@keynesiancross要求“[罗兰的代码中关于变量是什么的评论”,而其他人完全错过了陈述的问题 . Roland以Bézier曲线作为输入开始(以获得完美匹配),这使得更难理解问题和(至少对我而言)解决方案 . 对于留下残差的输入,插值的差异更容易看出 . 这是释义代码和非贝塞尔输入 - 以及意想不到的结果 .
这适用于
fcn = np.cos
但不适用于log
. 我有点期望拟合会使用控制点的t分量作为额外的自由度,就像拖动控制点一样:我猜测,失败的原因是标准测量曲线上点之间的距离,而不是一条曲线上的点与另一条曲线上最近点之间的距离 .