创建立方和/或二次贝塞尔曲线以适合路径

时间:2015-04-13 18:35:32

标签: algorithm lua interpolation curve-fitting bezier

我正在Lua工作2D游戏。 我有一个由许多点组成的路径,例如,点A到L:points A to L

我想沿着这条路径顺利移动一个物体。为了实现这一点,我想基于这些点创建二次或三次贝塞尔曲线,并插入这些曲线。但是,如何正确拟合曲线,以便在例如路径不被破坏的情况下。曲线停止,另一条曲线从F点开始

2 个答案:

答案 0 :(得分:0)

此问题解释了曲线拟合:How can I fit a Bézier curve to a set of data?

然而,有一种必须更简单的插值方法。就是这样:

  1. 优化:在每个边缘的中间放置一个点。
  2. Dual :在每个边缘的中间放置一个点并删除旧点。
  3. 多次重复 Dual 步骤。
  4. 从第一步开始重复,直到曲线足够平滑。
  5. 您可以很容易地看到它在纸上工作。得到的曲线开始逼近一系列贝塞尔样条曲线。

    本PDF文件(第3节)更正式地描述:http://www.cc.gatech.edu/~jarek/courses/handouts/curves.pdf

    以下是一些Javascript代码:

    function bspline_smooth(points, order) {
    
        // insert a point in the middle of each edge.
        function _refine(points) {
          var i, index, len, point, refined;
          points = [points[0]].concat(points).concat(points[points.length-1]);
          refined = [];
          index = 0;
          for (i = 0, len = points.length; i < len; i++) {
            point = points[i];
            refined[index * 2] = point;
            if (points[index + 1]) {
              refined[index * 2 + 1] = _mid(point, points[index + 1]);
            }
            index += 1;
          }
          return refined;
        }
    
        // insert point in the middle of each edge and remove the old points.
        function _dual(points) {
          var dualed, i, index, len, point;
          dualed = [];
          index = 0;
          for (i = 0, len = points.length; i < len; i++) {
            point = points[i];
            if (points[index + 1]) {
              dualed[index] = _mid(point, points[index + 1]);
            }
            index += 1;
          }
          return dualed;
        }
    
        function _mid(a, b) {
          return new Point(
            a.x + ((b.x - a.x) / 2),
            a.y + ((b.y - a.y) / 2) );
        }
    
        if (!order) {
           return points;
        }
        return bspline_smooth(_dual(_dual(_refine(points))), order - 1);
    }
    

答案 1 :(得分:-3)

你不需要知道数学就可以了。

使用单独的贝塞尔曲线将每个点与下一个点连接。

Bezier曲线的末端附有“手柄”。这些手柄与曲线相切(在终点处)。要制作一条“平滑”的路径,您需要做的就是将每两条相邻贝塞尔曲线的手柄“坐”在一条线上。

要理解这一点,请尝试使用像GIMP这样的绘图程序(但几乎任何其他软件都可以这样做)。这样的程序甚至有一个特殊的键,使相邻曲线的“手柄”位于一条直线上(并具有相同的长度)。

您必须做出的唯一“硬”数学决定是确定这些手柄的长度。实验。您可能希望使它取决于每3个连续点偏离直线的距离,或者取决于点之间的距离。

最后,至于沿着曲线以一个看似恒定的速度移动一个点(你的“物体”):你可以使用方法like this one的改编。