如何计算沿(贝塞尔曲线)移动的 1/4 圆弧?
How calculate a 1/4 circle arc to move along (bezier curve)?
我正在使用 JQuery.path 沿着贝塞尔曲线移动对象。单击该项目时,我可以确定起点和终点。如何计算角度和长度,使元素在与起点和终点相交的 1/4 圆弧上从 A 点移动到 B 点?
我基本上希望它 沿着一条曲线移动,该曲线永远不会低于起始 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)
}
);
大约。我想要的是:
大约是我得到的(它们浸得太低了):
如果 "what you want" 确实是 您所需要的,即 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。
通用解决方案有点棘手,因为它必须处理四个对角方向、水平方向和垂直方向中的每一个方向的对角线移动。
首先,您需要几个实用函数:
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
的计算对于每种情况(四个对角线,水平和垂直)都非常简单,但对于通用解决方案来说有点棘手。我花了一段时间才开发出适用于所有情况的东西。
我正在使用 JQuery.path 沿着贝塞尔曲线移动对象。单击该项目时,我可以确定起点和终点。如何计算角度和长度,使元素在与起点和终点相交的 1/4 圆弧上从 A 点移动到 B 点?
我基本上希望它 沿着一条曲线移动,该曲线永远不会低于起始 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)
}
);
大约。我想要的是:
大约是我得到的(它们浸得太低了):
如果 "what you want" 确实是 您所需要的,即 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。
通用解决方案有点棘手,因为它必须处理四个对角方向、水平方向和垂直方向中的每一个方向的对角线移动。
首先,您需要几个实用函数:
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
的计算对于每种情况(四个对角线,水平和垂直)都非常简单,但对于通用解决方案来说有点棘手。我花了一段时间才开发出适用于所有情况的东西。