Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将分割三次贝塞尔外推到1,1_Javascript_Css Transitions_Bezier_Cubic - Fatal编程技术网

Javascript 将分割三次贝塞尔外推到1,1

Javascript 将分割三次贝塞尔外推到1,1,javascript,css-transitions,bezier,cubic,Javascript,Css Transitions,Bezier,Cubic,我需要这里提供的解决方案的帮助 我需要修改它,以便在拆分后将返回的left和rights外推到1,1。这是因为如果我不外推,我不能使用返回的分割立方贝塞尔作为css转换 这就是我做的测试。请提供帮助,因为real与mike way不匹配:(我认为问题是我需要将结果推断为1,1。我不能简单地将值加倍,尽管我非常确定 真实的 ease-in-out是cubic-bezier(.42,0,58,1)图形上是 前半部分是ease in,它是三次贝塞尔(.42,0,1,1),图形上是 seoncd的

我需要这里提供的解决方案的帮助

我需要修改它,以便在拆分后将返回的left和rights外推到
1,1
。这是因为如果我不外推,我不能使用返回的分割立方贝塞尔作为css转换

这就是我做的测试。请提供帮助,因为real与mike way不匹配:(我认为问题是我需要将结果推断为1,1。我不能简单地将值加倍,尽管我非常确定

  • 真实的
    • ease-in-out
      cubic-bezier(.42,0,58,1)
      图形上是
    • 前半部分是
      ease in
      ,它是
      三次贝塞尔(.42,0,1,1)
      ,图形上是
    • seoncd的一半是
      ease out
      ,它是
      cubic bezier(0,0,58,1)
      ,grpahilly是
  • 上面发布的函数返回以下内容
    • ease-in-out
      与这一起点相同
    • 左上半部分为
      三次贝塞尔(0.21,0,0.355,0.25)
      ,图形显示为
      • 返回的代码:
        左:[0,0,0.21,0,0.355,0.25,0.5,0.5]
    • 右下半部分为
      三次贝塞尔(0.645,0.75,0.79,1)
      ,图形为
      • 返回的代码
        右侧:[0.5,0.5,0.645,0.75,0.79,1,1,1]
按Mike方式获取的代码如下:

var result = split({
    z: .5,
    x: [0, 0.42, 0.58, 1],
    y: [0, 0, 1, 1]
});
alert(result.toSource());
前半部分是易用性,其中是立方贝塞尔(.42,0,1,1),图形上是

请验证此假设。(曲线原始终点为a中的0,0和1,1) 贝塞尔曲线的前半部分[0,0,42,0,58,1,1,1]不应为[0,0.42,0,1,1,1] 端点是正确的(在缩放到1,1后),但在那里失去了连续性

Mike算法返回的值是正确的

来解释为什么你的假设可能是错误的

您用于拆分的算法是一种众所周知的算法,称为de Casteljau算法。此方法可以用非常简单的方式进行几何表示。请查看有关如何在任意点拆分的动画演示


但是,您可能很快就会遇到一个问题,即尝试正确缩放贝塞尔曲线的分割部分以适合单位正方形,端点固定在0,0和1,1。这可能您可以在纸上很容易地尝试。最简单的方法可能是线性缩放贝塞尔曲线的控制点,但在大多数情况下,您会得到一条挤压的曲线。

我创建了一个修改版的Mike分割函数,使其适合单位平方:)它使用hkrish的指针进行坐标标准化

只需将参数
fitUnitCell
设置为true.)


有趣的是,这实际上不是de Casteljau的算法——我提供的代码是基于使用矩阵表示法解决“分裂”问题的直接公式,而不是迭代的de Casteljau方法。当然,结果是一样的,但步骤的数量不同(事实上,在德·卡斯特尔约的原始论文中,他以扩展的形式写道(“courbes et surfaces`a pˆoles”)。他并没有确切地建议循环或任何迭代!:P当然,同样的事情也可以通过以矩阵形式书写伯恩斯坦基得到。我需要弄到那张纸=P(同样,使用现代html,重音字母应该很好=)这张纸,很遗憾,是以未发表的笔记的形式。我不确定我们是否能在网上找到它。你可以从Farouki或Farin关于这个主题的论文中找到原稿相关部分的扫描图,包括立方的展开形式和递归关系的推导。有趣的是,德卡斯特卢并没有与伯恩斯坦基础建立明确的关系。尽管他对评估曲线的想法更为笼统,但对于较低的阶数,他只是按原样写下了递推关系。(关于口音,我是从pdf复制的,可能是因为:)。谢谢@Mike'Pomax'Kamermans和hkrish的帮助。我正在重新做这件事,并将报告我的想法:)特别感谢hkrish的可视化,这太棒了!!
function splitCubicBezier(options) {
  var z = options.z,
      cz = z-1,
      z2 = z*z,
      cz2 = cz*cz,
      z3 = z2*z,
      cz3 = cz2*cz,
      x = options.x,
      y = options.y;

  var left = [
    x[0],
    y[0],
    z*x[1] - cz*x[0], 
    z*y[1] - cz*y[0], 
    z2*x[2] - 2*z*cz*x[1] + cz2*x[0],
    z2*y[2] - 2*z*cz*y[1] + cz2*y[0],
    z3*x[3] - 3*z2*cz*x[2] + 3*z*cz2*x[1] - cz3*x[0],
    z3*y[3] - 3*z2*cz*y[2] + 3*z*cz2*y[1] - cz3*y[0]];

  var right = [
    z3*x[3] - 3*z2*cz*x[2] + 3*z*cz2*x[1] - cz3*x[0],
    z3*y[3] - 3*z2*cz*y[2] + 3*z*cz2*y[1] - cz3*y[0],
                    z2*x[3] - 2*z*cz*x[2] + cz2*x[1],
                    z2*y[3] - 2*z*cz*y[2] + cz2*y[1],
                                    z*x[3] - cz*x[2], 
                                    z*y[3] - cz*y[2], 
                                                x[3],
                                                y[3]];

  if (options.fitUnitSquare) {
    return {
      left: left.map(function(el, i) {
        if (i % 2 == 0) {
          //return el * (1 / left[6])
          var Xmin = left[0];
          var Xmax = left[6]; //should be 1
          var Sx = 1 / (Xmax - Xmin);
          return (el - Xmin) * Sx;
        } else {
          //return el * (1 / left[7])
          var Ymin = left[1];
          var Ymax = left[7]; //should be 1
          var Sy = 1 / (Ymax - Ymin);
          return (el - Ymin) * Sy;
        }
      }),
      right: right.map(function(el, i) {
        if (i % 2 == 0) {
          //xval
          var Xmin = right[0]; //should be 0
          var Xmax = right[6];
          var Sx = 1 / (Xmax - Xmin);
          return (el - Xmin) * Sx;
        } else {
          //yval
          var Ymin = right[1]; //should be 0
          var Ymax = right[7];
          var Sy = 1 / (Ymax - Ymin);
          return (el - Ymin) * Sy;
        }
      })
    }
  } else {
   return { left: left, right: right};
  }
}

var easeInOut = {
  xs: [0, .42, .58, 1],
  ys: [0,   0,   1, 1]
};


var splitRes = splitCubicBezier({
  z: .5,
  x: easeInOut.xs,
  y: easeInOut.ys,
  fitUnitSquare: false
});

alert(splitRes.toSource())