我正在画画"关闭"使用样条线算法的数字,当我尝试在最后填充它时,我没有得到预期的结果。如果您想使用它来查看来源http://jsfiddle.net/9CJv6/14/
var canvas = document.getElementById('canvas');
var points = [100, 300, 10, 150, 100, 180, 120,10, 400,200];
var context = canvas.getContext('2d');
drawSpline(context, points, 0.4);
function drawSpline(ctx, pts, t){
ctx.lineWidth = 3;
var cp = []; // array of control points, as x0,y0,x1,y1,...
var n = pts.length;
// Append and prepend knots and control points to close the curve
pts.push(pts[0],pts[1],pts[2],pts[3]);
pts.unshift(pts[n-1]);
pts.unshift(pts[n-1]);
for (var j = 0; j < n; j += 2){
cp = cp.concat(getControlPoints(pts[j],pts[j+1],pts[j+2],pts[j+3],pts[j+4],pts[j+5],t));
}
cp = cp.concat(cp[0], cp[1]);
ctx.strokeStyle = 'red';
ctx.fillStyle = "yellow";
ctx.beginPath();
for(var i = 2; i < n+2; i += 2){
ctx.moveTo(pts[i], pts[i+1]);
ctx.bezierCurveTo(cp[2*i-2], cp[2*i-1], cp[2*i], cp[2*i+1], pts[i+2], pts[i+3]);
}
ctx.stroke();
ctx.fill();
}
function getControlPoints(x0,y0,x1,y1,x2,y2,t){
// x0,y0,x1,y1 are the coordinates of the end (knot) pts of this segment
// x2,y2 is the next knot -- not connected here but needed to calculate p2
// p1 is the control point calculated here, from x1 back toward x0.
// p2 is the next control point, calculated here and returned to become the
// next segment's p1.
// t is the 'tension' which controls how far the control points spread.
// Scaling factors: distances from this knot to the previous and following knots.
var d01=Math.sqrt(Math.pow(x1-x0,2)+Math.pow(y1-y0,2));
var d12=Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));
var fa=t*d01/(d01+d12);
var fb=t-fa;
var p1x=x1+fa*(x0-x2);
var p1y=y1+fa*(y0-y2);
var p2x=x1-fb*(x0-x2);
var p2y=y1-fb*(y0-y2);
return [p1x,p1y,p2x,p2y]
}
这是我得到的:
这就是我的期望:
答案 0 :(得分:1)
Bezier曲线的端点未连接以形成闭合路径。因此,您有多条独立曲线(如在顶部图像中),而不是一条闭合曲线(如底部图像中所示)。
例如,请参阅&#34; hitch&#34;在你图像的这一部分。
每个上一条曲线的终点必须是下一条曲线的起点,否则曲线不会被关闭。
你可以通过删除循环中的ctx.moveTo
来实现这一目标,但是你需要关闭最后一个底部:
for(var i = 2; i < n+2; i += 2){
ctx.bezierCurveTo(cp[2*i-2], cp[2*i-1], cp[2*i], cp[2*i+1], pts[i+2], pts[i+3]);
}