如何计算1/4圆弧移动(贝塞尔曲线)?

时间:2015-07-20 23:10:25

标签: javascript jquery bezier

我使用JQuery.path沿贝塞尔曲线移动物体。单击该项目时,我可以确定起点和终点。如何计算角度和长度,使元素在圆弧上从A点移动到B点,该圆弧是与起点和终点相交的圆的1/4?

我基本上希望它沿着一条从不低于起始y位置的曲线移动,并且永远不会移动到末尾x位置的左侧。

    var path = {
        start: {
            x: currentLeft,
            y: currentTop,
            angle: ????, //Don't know how to calculate this
            length: ???? //Don't know how to calculate this
        },
        end: {
            x: endLeft,
            y: endTop,
            angle: ????, //Don't know how to calculate this
            length: ???? //Don't know how to calculate this
        }
    };

    jQuery(myElement).animate(
        {
            path: new jQuery.path.bezier(path)
        }
    );

约我想要的是: enter image description here

接近我得到的东西(他们di di太低): enter image description here

2 个答案:

答案 0 :(得分:3)

广义解决方案有点棘手,因为它必须处理四个对角线方向,水平方向和垂直方向中的对角线移动。

首先,您需要一些实用功能:

function r2d(x) {
    /* radians to degrees */
    return x * 180 / Math.PI;
}
function smaller(x, y) {
    /* returns the closer of x|y to zero */
    var x_ = Math.abs(x);
    var y_ = Math.abs(y);
    return (Math.min(x_, y_) === x_) ? x : y;
}

现在一个主函数anim接受一个jQuery对象(包含感兴趣的元素)和一个end对象(具有属性.left和.top)。

function anim($el, end) {
    var current = $el.position();

    var slope1 = (end.top - current.top) / (end.left - current.left);
    var slope2 = 1 / slope1;
    var endAngle = r2d(Math.atan(smaller(slope1, slope2)));
    var startAngle = -endAngle;
    var length = 1/3; //Vary between 0 and 1 to affect the path's curvature. Also, try >1 for an interesting effect.

    //For debugging
    $("#endAngle").text(endAngle);
    $("#startAngle").text(startAngle);
    $("#length").text(length);

    var path = {
        start: {
            x: current.left,
            y: current.top,
            angle: startAngle,
            length: length
        },
        end: {
            x: end.left,
            y: end.top,
            angle: endAngle,
            length: length
        }
    };

    $el.animate({ path: new jQuery.path.bezier(path) });
}

endAngle的计算对于每个个案(四个对角线,水平和垂直)都非常简单,但对于广义解决方案来说有点棘手。我花了一些时间开发出适用于所有情况的东西。

<强> DEMO

答案 1 :(得分:1)

如果“你想要的东西”真的你需要什么,即90度离开和到达,那么我们可以立即解决这个问题:

p_start = { X:..., Y:... }
p_end = { X:..., Y:... }
dx = p_end.X - p_start.X
dy = p_end.Y - p_start.Y
control_1 = { X: p_start.X, Y: p_start.Y + 0.55228 * dy }
control_2 = { X: p_end.X - 0.55228 * dx, Y: p_end.Y }

完成了。我们基本上做的是假装起点和终点位于一个圆上,计算机控制点使得得到的贝塞尔曲线在四分之一圆弧处具有最小误差。

就角度而言:偏离开始始终为角度π/ 2,到达终点的距离始终为角度0。