【问题标题】:Optimize the parameterization algorithm of a cubic bezier curve优化三次贝塞尔曲线的参数化算法
【发布时间】:2013-03-13 10:46:53
【问题描述】:

除了使用查找表之外,还有其他方法可以优化像这样的三次贝塞尔曲线的参数化算法吗? (5000 步的参数化对于速度较慢的 PC 来说实在是太多了,因为我需要在 1 秒内多次调用此函数):

function parameterizeCurve(path, partArc, initialT)
{
   // curve length is already known and globally defined
   // brute force
   var STEPS = 5000; // > precision
   var t = 1 / STEPS;
   var aX=0;
   var aY=0;
   var bX=path[0], bY=path[1];
   var dX=0, dY=0;
   var dS = 0;
   var sumArc = 0;
   var arrT = new Array(Math.round(partArc)); 
   var z = 1;
   arrT[0] = -1;

   var oldpartArc = partArc;
   partArc = partArc - initialT;

   var j = 0;

   for (var i=0; i<STEPS; j = j + t) {
      aX = bezierPoint(j, path[0], path[2], path[4], path[6]);
      aY = bezierPoint(j, path[1], path[3], path[5], path[7]);

      dX = aX - bX;
      dY = aY - bY;
      // deltaS. Pitagora
      dS = Math.sqrt((dX * dX) + (dY * dY));
      sumArc = sumArc + dS;
      if (sumArc >= partArc) {
         arrT[z] = j; // save current t
         z++;
         sumArc = 0;
         partArc = oldpartArc;
      }
      bX = aX;
      bY = aY;
      i++;
   }

   return arrT;
}


    function bezierPoint(t, o1, c1, c2, e1) {
        var C1 = (e1 - (3.0 * c2) + (3.0 * c1) - o1);
        var C2 = ((3.0 * c2) - (6.0 * c1) + (3.0 * o1));
        var C3 = ((3.0 * c1) - (3.0 * o1));
        var C4 = (o1);

        return ((C1*t*t*t) + (C2*t*t) + (C3*t) + C4)
    }

【问题讨论】:

  • 输入是什么?你在优化什么?看起来您正在尝试最大化某种距离..
  • 参数化是数学中众所周知的事情。我需要在曲线上放置等距元素。
  • 曲线是如何定义的?它是分段的 3 度贝塞尔曲线还是其他?顺便说一句,我拥有数学硕士学位
  • 三次贝塞尔曲线,以 1 开始 1 结束 2 个控制点。 path[0] 和 path[1] 是起点 X 和起点 Y。路径 6 和 7 是终点。其他是控制点。请阅读下面答案中的 cmets..
  • 我编辑了源代码并添加了 BezierPoint 函数。

标签: math graphics


【解决方案1】:

如果我猜对了,您正试图提出一个沿曲线以恒定速度移动的三次贝塞尔曲线参数化。

那么,为什么需要 5000 步?可以沿着曲线移动的最小值是一个像素。贝塞尔曲线停留在其四个控制点的凸包内,因此曲线的长度将小于折线P0 -&gt; P1 -&gt; P2 -&gt; P3 的长度。因此,找到以像素为单位的长度,并使用它(而不是 5000)。

让我知道这是否足够加快速度。

【讨论】:

  • 我不明白,但我想要实现的是在曲线上放置一些应该彼此距离相等的元素。我经常这样做,因为曲线会发生变化。所以我需要曲线上的项目在一个非常精确的位置。如果我执行少于 5000 次循环,整个动画(项目)开始在曲线上跳动一点,因为参数化不是那么精确..应该避免这种效果,而且不应该那么昂贵。
  • 动画控制点确实使这个问题变得更加困难。我的建议是根据连接控制点的线的长度调整 STEPS,而不是将其值固定为 5000。
  • 我在那里所做的只是简单地遍历曲线的 t 5000 次,直到曲线结束。由于 t 的密度在每个地方都不相等(例如,在最弯曲的地方,相同 t 之间的弧线不同,然后在曲线的更直的地方)我需要遍历整个曲线。因此,如果我把曲线的长度而不是 5000 放在那里,那么输出数字就不那么精确了,当曲线改变他的控制点时,我得到的项目在曲线上跳舞。
  • 嗯,您可以尝试“二分查找”方法来查找 t。首先尝试t=1/5000,然后尝试2*t,看是否超过弧长。如果没有,再加倍,等等。如果超过,则转到1.5*t,等等。
  • 太棒了。我有 200-300 步,有一定的曲线倾斜度!
猜你喜欢
  • 2011-03-10
  • 2018-12-03
  • 1970-01-01
  • 2012-07-27
  • 1970-01-01
  • 1970-01-01
  • 2016-06-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多