我有一个由多个段组成的Cubic Bezier曲线(左图)。它有一些粗糙的曲率,我需要让它像正确的图像一样平滑。这个问题有点像“降噪”,我该如何实现呢?
有类似的线程here,但输入是一组点,并使用最小二乘拟合贝塞尔曲线,但在我的问题中,输入已经是立方贝塞尔曲线。
在上面的图片中,我不会绘制细分和控制点,但我希望你能理解。
答案 0 :(得分:2)
您想保留相同数量的细分吗?您需要保持Bezier细分市场之间的连续性吗?您是想尝试触及一定数量的段,还是只是将事物保持在原始曲线的某个容差范围内?
现在我假设你想要减少Bezier段的数量,你需要保持段之间的G1连续性,并且你试图在公差范围内平滑(只是从你的图像猜测)。 / p>
对于顶级算法,您将遍历每对相邻的曲线,并尝试将它们组合在一起。重复此操作,直到组合两条相邻曲线超出公差范围。
如何组合两条相邻的贝塞尔曲线?假设它们是曲线P和Q,并且因为它们都是立方体,所以它们各有4个CV,P0,P1,P2,P3和Q0,Q1,Q2,Q3。我们还假设P3 == Q0。另外,我们可以说输出曲线是R,由R0,R1,R2,R3组成。
另一个非常重要的步骤 - 您需要为您正在简化的较大曲线中的每个贝塞尔曲线段分配t值。因此,段0将从0..1开始,段1从1..2开始,段2从2..3开始,等等。
如果你想保持P与邻居的连续性,以及Q与邻居的连续性,你不能移动P0或Q3,由(P1-P0)和(Q2-Q3)形成的切向量必须保持在同样的方向..它们只能缩放。
由于R中只有4个CV,因此这两个比例因子是您拥有的唯一自由度。我们称之为kp和kq。
R0=P0
R1=P0+kp*(P1-P0)
R2=Q3+kq*(Q2-Q3)
R3=Q3
如果两条曲线的结长度相等,则kp = 2且kq = 2.
答案 1 :(得分:1)
我前一段时间做过这样的事情:
一些建议:
删除即可
移除后,您需要重新计算两侧剩余结的手柄长度,然后测量移除导致的错误(移除成本)。 有关最小二乘切线长度计算的示例,请参阅FitCurve.c。
成本'每次删除都可以放入最小堆, 然后你可以从堆顶部弹出成本最低的元素(重新评估相邻节点移除后的相邻成本)。
继承人C code that does just this。
您可以将曲线评估为一个简单的多边形,然后在结果点上运行曲线拟合算法,并使用较低的误差阈值。
一旦你已经拥有曲线拟合功能,添加此选项,因为它的显着减少了麻烦。
这可能不会给出相当好的结果,但它可能足以满足您的目的。
由于您可以使用现有的曲线拟合库(own open-source library linked here)。