【问题标题】:Generating a cubic bezier curve from rough points从粗糙点生成三次贝塞尔曲线
【发布时间】:2010-07-12 04:21:04
【问题描述】:

我正在寻找一种方法来使我的应用程序在手绘模式下产生更流畅的结果。现在它只是简单地添加每个鼠标移动点并从中制作一个多边形。我注意到现代矢量应用程序会产生贝塞尔曲线,使其看起来更平滑,我想知道这是怎么做到的?那么如何通过平滑曲线的粗略用户输入获得 4 个点来进行贝塞尔插值呢?

谢谢

【问题讨论】:

  • 等等,好的,所以你的问题不在于如何从你拥有的所有点中创建贝塞尔曲线,问题是你有太多的点,你想转动任意数字没有必要直接从所有点或您作为输入的任何点生成的平滑曲线?
  • 是的,这就是我要找的
  • 您可以将其视为信号处理问题并对您的点进行下采样(即具有两个分量的时间信号,将其视为立体声音频或其他东西)
  • 首先,我想你会发现这些程序中的大多数将路径变成了海峡和弯曲(贝塞尔)路径的混合,所以你可以有尖角等。

标签: c++ c algorithm graphics vector


【解决方案1】:

如果要解决一般问题,可以使用levenberg-marquardt (LM) 优化。

您想定义一个包含少量点的贝塞尔曲线。您可以使用 LM 通过最小化所有点到曲线的平方距离来优化曲线的参数(点位置)。这是您的目标函数,即距离平方和。

诀窍是计算 LM 的梯度和粗麻布。您可以在数字上执行此操作,而无需进行任何数学运算。使用numerical differentiation 计算雅可比 (J),用于计算梯度。 (LM 也使用 Jacobian 矩阵来逼近 Hessian 矩阵。)

Matti 提到了用于平滑样条的 GSL。我不知道 GSL,但事实证明它有 LM 和数值微分的实现。

【讨论】:

    【解决方案2】:

    仅当您与最后一个点相距一定距离阈值时才存储一个新点怎么样?

    【讨论】:

    • 如果你扔掉一大堆有意义的点,然后决定保留一个稀有的离群点怎么办?
    【解决方案3】:

    类似但不完全类似ransac(请参阅Ransac)的东西在这里可能会很好地工作。 Ransac 在消除异常值的同时找到了解决方案。当从一小部分数据生成假设并且易于针对整个数据集测试假设时,Ransac 是很好的。这非常适合您的问题。

    基本思路:
    循环:

    1. 从完整集合中随机选取少量点来创建贝塞尔曲线。
    2. 计算您拥有的每个点到该曲线的距离。
    3. 消除超过某个阈值的点。

    4. 将剩余分数的平方距离相加。
    5. 保留得分最高的解决方案。

    要真正完成这个任务,您需要为 4 找到一个函数来解决您最初的问题。哦。也就是说,您需要能够根据步骤 3 中未消除的所有点来计算曲线。这就是我提出上述建议的原因。它既快速又简单,可能会让您非常接近,尤其是因为您确实没有严重的异常值。

    【讨论】:

      【解决方案4】:

      您也可以使用平滑样条。如果您对 GPL 没问题,请查看 GSL http://www.gnu.org/software/gsl/ 的实现。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-10
        • 2012-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-24
        • 2017-12-12
        • 1970-01-01
        相关资源
        最近更新 更多