我工作在HTML5画布游戏。Bezier曲线总是相同的长度
我想是画两个点之间的S形三次Bezier曲线,但我正在寻找一种方式来计算控制点的坐标,以便曲线本身始终是相同的长度无论怎么接近那些没有点直到达到曲线成为直线的点。
我工作在HTML5画布游戏。Bezier曲线总是相同的长度
我想是画两个点之间的S形三次Bezier曲线,但我正在寻找一种方式来计算控制点的坐标,以便曲线本身始终是相同的长度无论怎么接近那些没有点直到达到曲线成为直线的点。
这是可解的数值。我假设你有一个有4个控制点的立方贝塞尔曲线。 在每一步你有第一个(P0)和最后一个(P3)点,并且你想计算P1和P2,使得总长度是恒定的。
添加该约束消除一个自由度,所以我们有1个左(开始与4,确定的终点(-2)和恒定长度是另一个-1)。所以你需要做出决定。
Bezier曲线是在0和1之间限定的多项式,需要在元件的总和的平方根整合(2D?)。对于一个三次贝塞尔曲线来说,这意味着一个6阶多项式的sqrt,这个wolfram不知道如何求解。但是,如果您已知所有其他控制点(或者已知某个其他约束的依赖关系),则可以为该约束存储预先计算值的保存表。
真的有必要,该曲线是贝塞尔曲线? 拟合总长度恒定的两个圆弧要容易得多。你将永远得到一个S形。
拟合两个圆弧的:
让d是在端点之间的欧几里德距离。让C是我们想要的恒定长度。我得到了下面的表达式为b(图像中绘制):
b = sqrt(D*sin(C/4)/4 - (D^2)/16)
,如果它是正确的,所以如果有人得到不同的东西,发表评论我没有检查。
编辑:您应该考虑的负面解决方案太,我得到求解方程时,检查哪一个是正确的。
b = -sqrt(D*sin(C/4)/4 - (D^2)/16)
下面是SVG这是接近纠正工作示例:
http://phrogz.net/svg/constant-length-bezier.xhtml
我实验确定,当端点上的一个顶部的另一个手柄应
desiredLength×COS(30°)
远离手柄;和(当然)当终点处于最大距离时,手柄应该处于彼此顶部。绘制所有理想的点看起来有点像椭圆:
蓝线是实际的理想公式,而上面的红线是椭圆逼近理想。使用椭圆公式(正如我上面的例子那样)可以使线在中间得到大约9%的时间。
下面是相关的JavaScript代码:
// M is the MoveTo command in SVG (the first point on the path)
// C is the CurveTo command in SVG:
// C.x is the end point of the path
// C.x1 is the first control point
// C.x2 is the second control point
function makeFixedLengthSCurve(path,length){
var dx = C.x - M.x, dy = C.y - M.y;
var len = Math.sqrt(dx*dx+dy*dy);
var angle = Math.atan2(dy,dx);
if (len >= length){
C.x = M.x + 100 * Math.cos(angle);
C.y = M.y + 100 * Math.sin(angle);
C.x1 = M.x; C.y1 = M.y;
C.x2 = C.x; C.y2 = C.y;
}else{
// Ellipse of major axis length and minor axis length*cos(30°)
var a = length, b = length*Math.cos(30*Math.PI/180);
var handleDistance = Math.sqrt(b*b * (1 - len*len/(a*a)));
C.x1 = M.x + handleDistance * Math.sin(angle);
C.y1 = M.y - handleDistance * Math.cos(angle);
C.x2 = C.x - handleDistance * Math.sin(angle);
C.y2 = C.y + handleDistance * Math.cos(angle);
}
}
也许查询表可以从实验确定的数据构建? – Harold
@Harold真,或简单的分段线性逼近。尽管如此,我仍然在寻找[数学上正确的答案](http://math.stackexchange.com/questions/85003/equation-for-control-point-distance-for-fixed-length-cubic-bezier-path -with-SPE)。 – Phrogz
[崇高目标](http://ressalva.files.wordpress.com/2011/06/yak_crop2.png)。与此同时,近似解决方案可能对HTML5帆布剪切克隆的作者有价值。 ;) – Harold
是它关键是线长的一模一样,或者只是在起点和终点越来越接近它得到零? – idanzalz
贝塞尔的程度是多少?它是立方体吗? (4点 - 开始,结束,中间2点) – idanzalz
一个快速而肮脏的解决方案是将其表述为一个优化问题:将曲线拆分为一系列直线段,并尽量减少这些段之间的总长度差线段和所需的恒定长度,重量免费的控制点。您可以使用诸如渐变下降http://en.wikipedia.org/wiki/Gradient_descent这样的算法。但分析解决方案会更好。 – Rulle