简体   繁体   English

如何计算贝塞尔曲线上的控制点?

[英]how to calculate control points on a bezier curve?

I do have a bezier curve, and at a certain point, I want a second bezier curve "branching off" the first curve in a smooth manner. 我确实有一个贝塞尔曲线,在某个点上,我想要第二个贝塞尔曲线以平滑的方式“分支”第一条曲线。 Together with calculating the intersection point (with a percentage following the Bezier curve), I need also the control point (the tangent and weight). 与计算相交点(遵循Bezier曲线的百分比)一起,我还需要控制点(切线和权重)。 The intersection point is calculated with the following piece of javascript: 相交点是使用以下javascript计算的:

getBezier = function getBez(percent,p1,cp1,cp2,p2) {
    function b1(t) { return t*t*t }
    function b2(t) { return 3*t*t*(1-t) }
    function b3(t) { return 3*t*(1-t)*(1-t) }
    function b4(t) { return (1-t)*(1-t)*(1-t) }
    var pos = {x:0,y:0};
    pos.x = p1.x*b1(percent) + cp1.x*b2(percent) + cp2.x*b3(percent) + p2.x*b4(percent);
    pos.y = p1.y*b1(percent) + cp1.y*b2(percent) + cp2.y*b3(percent) + p2.y*b4(percent);
    return pos;
}

(Non IE browsers can see it in action at http:// www.iscriptdesign.com -> Tutorial -> Groups & Paths). (非IE浏览器可以在http: //www.iscriptdesign.com- >教程->组和路径中查看它的运行情况)。 All I need now is the controlpoint or (tangent and weight) for the branchpoint ( I don't have a clue where to start, and I hope somebody can point to some code, or mathematical equation, if possible as function from the same parameters as the getBezier function above). 我现在需要的只是分支点的控制点或(切线和权重)(我不知道从哪里开始,我希望有人可以指向一些代码或数学方程式,如果可能的话,可以使用相同的参数作为函数)就像上面的getBezier函数一样)。

Found and implemented it: de-Casteljau algorithm turned out to be the fastest implementable solution. 找到并实现它: de-Casteljau算法被证明是最快的可实现解决方案。 It is currently present under: iScriptDesign (Tutorial ->Spit Bezier). 当前位于: iScriptDesign (教程-> Spit Bezier)。

Example usage (I think, i need help from @drjerry) 用法示例(我认为,我需要@drjerry的帮助)

I have a css3 timing function, this is called ease-in-out: cubic-bezier(.42,0,.58,1) . 我有一个css3计时函数,这称为ease-in-out: cubic-bezier(.42,0,.58,1) Graphically this looks like: http://cubic-bezier.com/#.42,0,.58,1 图形上看起来像: http : //cubic-bezier.com/#.42,0,.58,1

I want to make a new timing function that is just the bottom half and then top half of this graph. 我想创建一个新的计时函数,该函数只是此图的下半部分,然后是上半部分。

So the bottom half is ease-in : cubic-bezier(.42,0,1,1) . 所以下半部分是ease-incubic-bezier(.42,0,1,1) Graphically: http://cubic-bezier.com/#.42,0,1,1 图形: http : //cubic-bezier.com/#.42,0,1,1

And the top half is ease-out : cubic-bezier(0,0,.58,1) . 上半部分是ease-outcubic-bezier(0,0,.58,1) Graphically: http://cubic-bezier.com/#0,0,.58,1 图形: http : //cubic-bezier.com/#0,0,.58,1

So now what confuses me is that according to the script at iScriptDesign it tells me they are different. 所以现在令我困惑的是,根据iScriptDesign上的脚本,它告诉我它们是不同的。

iScriptDeisgn says the starting half of ease-in-out is (which is ease-in ) is: cubic-bezier(.21, 0, .355, .25) . iScriptDeisgn表示, ease-in-out的开始一半是( ease-in ): cubic-bezier(.21, 0, .355, .25) Graphically: http://cubic-bezier.com/#.21,0,.35,.25 图形: http : //cubic-bezier.com/#.21,0,.35,.25

iScriptDeisgn says the ending half of ease-in-out is (which is ease-out ) is: cubic-bezier(.145, .25, .29, .5) . iScriptDeisgn表示, ease-in-out后半部分(即ease-out )为: cubic-bezier(.145, .25, .29, .5) Graphically: http://cubic-bezier.com/#.14,.25,.29,.5 图形: http : //cubic-bezier.com/#.14,.25,.29,.5

Why is the ease-in and ease-out returned by the iScriptDesign split function different from the real ease-in and real ease-out ? 为什么ease-inease-out由iScriptDesign返回拆分功能与现实不同的ease-in和真正的ease-out I don't get it. 我不明白

Code for this example. 此示例代码。

//////////////////START FROM ISCRIPTDESIGN
var splitBezier = function(array, perc) {
    array.unshift({x:0, y:0});
    var coll = [];
    while (array.length > 0) {
    for (var i = 0;i < array.length-1; i++) {
        coll.unshift(array[i]);
        array[i] = interpolate(array[i], array[i+1], perc);
    }
    coll.unshift(array.pop());
    }
    return {b1: [{x:coll[5].x, y:coll[5].y}, {x:coll[2].x, y:coll[2].y},{x:coll[0].x, y:coll[0].y}]
        , b2: [{x:coll[1].x - coll[0].x,y:coll[1].y-coll[0].y}, {x:coll[3].x - coll[0].x,y:coll[3].y-coll[0].y}, {x:coll[6].x - coll[0].x,y:coll[6].y-coll[0].y}]};
}

var interpolate = function (p0, p1, percent) {
    if (typeof percent === 'undefined') percent = 0.5;  
    return  {x: p0.x + (p1.x - p0.x) * percent
         , y: p0.y + (p1.y - p0.y) * percent};
}
//////////////////END FROM ISCRIPTDESIGN
var coord = function (x,y) {
  if(!x) var x=0;
  if(!y) var y=0;
  return {x: x, y: y};
}
var easeInOut = [new coord(.42,0), new coord(.58,1), new coord(1,1)];
var split50percent = splitBezier(easeInOut.slice(), .5);

So split50percent is set to: 因此split50percent设置为:

({
    b1: [{
        x: 0.21,
        y: 0
    }, {
        x: 0.355,
        y: 0.25
    }, {
        x: 0.5,
        y: 0.5
    }],
    b2: [{
        x: 0.14500000000000002,
        y: 0.25
    }, {
        x: 0.29000000000000004,
        y: 0.5
    }, {
        x: 0.5,
        y: 0.5
    }]
})

Same thing with easeInOutSine easeInOutSine

  • easeInOutSine :.44,.05,.55,.95 easeInOutSine :.44,.05,.55,.95
  • REAL 真实
    • easeInSine :0.47, 0, 0.745, 0.715 easeInSineeaseInSine
    • easeOutSine :0.39, 0.575, 0.565, 1 easeOutSineeaseOutSine
  • iScriptDesign iScriptDesign
    • easeInSine :.22,.03,.36,.26 easeInSine :.22,.03,.36,.26
    • easeOutSine :.14,.24,.28,.48 easeOutSine :.14,.24,.28,.48

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM