Как рассчитать контрольные точки на кривой Безье? - PullRequest
2 голосов
/ 18 октября 2010

У меня есть кривая Безье, и в определенный момент я хочу, чтобы вторая кривая Безье плавно разветвлялась на первую кривую.Вместе с вычислением точки пересечения (с процентом, следующим за кривой Безье), мне также нужна контрольная точка (тангенс и вес).Точка пересечения рассчитывается с помощью следующего фрагмента 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;
}

(браузеры, не поддерживающие IE, могут увидеть его в действии на http:// www.iscriptdesign.com -> Tutorial -> Groups & Paths. Все, что мне сейчас нужно, это контрольная точка или (тангенс и вес) для точки ветвления (я понятия не имею, с чего начать, и я надеюсь, что кто-то может указать на некоторыекод или математическое уравнение, если это возможно, как функция из тех же параметров, что и функция getBezier, описанная выше).

Ответы [ 2 ]

1 голос
/ 08 ноября 2010

Нашел и реализовал: алгоритм de-Casteljau оказался самым быстрым реализуемым решением.В настоящее время он присутствует в: iScriptDesign (Учебное пособие -> Spit Bezier).

0 голосов
/ 04 мая 2014

Пример использования (я думаю, мне нужна помощь @drjerry)

У меня есть функция синхронизации css3, она называется easy-in-out: cubic-bezier(.42,0,.58,1). Графически это выглядит так: http://cubic -bezier.com / #. 42,0, .58,1

Я хочу создать новую функцию синхронизации, которая будет только нижней половиной, а затем верхней половиной этого графика.

Таким образом, нижняя половина - ease-in: cubic-bezier(.42,0,1,1). Графически: http://cubic -bezier.com / #. 42,0,1,1

А верхняя половина - ease-out: cubic-bezier(0,0,.58,1). Графически: http://cubic -bezier.com / # 0,0, .58,1

Итак, что меня смущает, так это то, что в соответствии со сценарием в iScriptDesign он говорит мне, что они разные.

iScriptDeisgn говорит, что начальная половина ease-in-out (то есть ease-in): cubic-bezier(.21, 0, .355, .25). Графически: http://cubic -bezier.com / #. 21,0, .35, .25

iScriptDeisgn говорит, что конечная половина ease-in-out равна (то есть ease-out): cubic-bezier(.145, .25, .29, .5). Графически: http://cubic -bezier.com / #. 14, .25, .29, .5

Почему ease-in и ease-out, возвращаемые функцией разделения iScriptDesign, отличаются от реального ease-in и реального ease-out? Я не понимаю.

Код для этого примера.

//////////////////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);

Итак, 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
    }]
})

То же самое с easeInOutSine

  • easeInOutSine :. 44, +0,05, +0,55, +0,95
  • РЕАЛЬНЫЙ
    • easeInSine: 0,47, 0, 0,745, 0,715
    • easeOutSine: 0,39, 0,575, 0,565, 1
  • iScriptDesign
    • easeInSine :. 22, +0,03, +0,36, +0,26
    • easeOutSine :. 14, +0,24, +0,28, +0,48
...