修剪贝塞尔曲线
此示例显示如何修剪贝塞尔曲线。
函数 trimBezier 修剪曲线的两端,将曲线 fromPos
返回到 toPos
。fromPos
和 toPos
在 0 到 1 的范围内,可以修剪二次曲线和三次曲线。曲线类型由最后一个 x 参数 x4
确定。如果不是 undefined
或 null
那么它假设曲线是立方的,否则曲线是二次曲线
修剪曲线作为点阵列返回。二次曲线为 6 个点,三次曲线为 8 个点。
示例用法
修剪二次曲线。
var p1 = {x : 10 , y : 100};
var p2 = {x : 100, y : 200};
var p3 = {x : 200, y : 0};
var newCurve = splitCurveAt(0.25, 0.75, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y)
var i = 0;
var p = newCurve
// Draw the trimmed curve
// Assumes ctx is canvas 2d context
ctx.lineWidth = 1;
ctx.strokeStyle = "black";
ctx.beginPath();
ctx.moveTo(p[i++],p[i++]);
ctx.quadraticCurveTo(p[i++], p[i++], p[i++], p[i++]);
ctx.stroke();
修剪三次曲线。
var p1 = {x : 10 , y : 100};
var p2 = {x : 100, y : 200};
var p3 = {x : 200, y : 0};
var p4 = {x : 300, y : 100};
var newCurve = splitCurveAt(0.25, 0.75, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y)
var i = 0;
var p = newCurve
// Draw the trimmed curve
// Assumes ctx is canvas 2d context
ctx.lineWidth = 1;
ctx.strokeStyle = "black";
ctx.beginPath();
ctx.moveTo(p[i++],p[i++]);
ctx.bezierCurveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]);
ctx.stroke();
示例函数
trimBezier = function(fromPos,toPos,x1,y1,x2,y2,x3,y3,[x4,y4])
注意: [x4,y4]内的参数是可选的。
注意: 此功能需要本节中的示例 Split Bezier Curves At 中的功能
var trimBezier = function(fromPos, toPos, x1, y1, x2, y2, x3, y3, x4, y4){
var quad, i, s, retBez;
quad = false;
if(x4 === undefined || x4 === null){
quad = true; // this is a quadratic bezier
}
if(fromPos > toPos){ // swap is from is after to
i = fromPos;
fromPos = toPos
toPos = i;
}
// clamp to on the curve
toPos = toPos <= 0 ? 0 : toPos >= 1 ? 1 : toPos;
fromPos = fromPos <= 0 ? 0 : fromPos >= 1 ? 1 : fromPos;
if(toPos === fromPos){
s = splitBezierAt(toPos, x1, y1, x2, y2, x3, y3, x4, y4);
i = quad ? 4 : 6;
retBez = [s[i], s[i+1], s[i], s[i+1], s[i], s[i+1]];
if(!quad){
retBez.push(s[i], s[i+1]);
}
return retBez;
}
if(toPos === 1 && fromPos === 0){ // no trimming required
retBez = [x1, y1, x2, y2, x3, y3]; // return original bezier
if(!quad){
retBez.push(x4, y4);
}
return retBez;
}
if(fromPos === 0){
if(toPos < 1){
s = splitBezierAt(toPos, x1, y1, x2, y2, x3, y3, x4, y4);
i = 0;
retBez = [s[i++], s[i++], s[i++], s[i++], s[i++], s[i++]];
if(!quad){
retBez.push(s[i++], s[i++]);
}
}
return retBez;
}
if(toPos === 1){
if(fromPos < 1){
s = splitBezierAt(toPos, x1, y1, x2, y2, x3, y3, x4, y4);
i = quad ? 4 : 6;
retBez = [s[i++], s[i++], s[i++], s[i++], s[i++], s[i++]];
if(!quad){
retBez.push(s[i++], s[i++]);
}
}
return retBez;
}
s = splitBezierAt(fromPos, x1, y1, x2, y2, x3, y3, x4, y4);
if(quad){
i = 4;
toPos = (toPos - fromPos) / (1 - fromPos);
s = splitBezierAt(toPos, s[i++], s[i++], s[i++], s[i++], s[i++], s[i++]);
i = 0;
retBez = [s[i++], s[i++], s[i++], s[i++], s[i++], s[i++]];
return retBez;
}
i = 6;
toPos = (toPos - fromPos) / (1 - fromPos);
s = splitBezierAt(toPos, s[i++], s[i++], s[i++], s[i++], s[i++], s[i++], s[i++], s[i++]);
i = 0;
retBez = [s[i++], s[i++], s[i++], s[i++], s[i++], s[i++], s[i++], s[i++]];
return retBez;
}