![](/img/trans.png)
[英]javascript - find coefficient/function for given points on cubic bezier curve
[英]Bezier path function by multiple points with native javascript
我需要贝塞尔 function 几个点并将其分开一些步骤。 Imagine a pirate map with a dashed line:) I have a single dash (some display object with x/y position and rotation ) for building this map
我发现 canvas 方法.quadraticCurveTo()
等,但我需要特定的 function 来将曲线与步骤分开
我使用较早的原生 function 作为基本贝塞尔曲线
function bezier(t, p0, p1, p2, p3){
var cX = 3 * (p1.x - p0.x),
bX = 3 * (p2.x - p1.x) - cX,
aX = p3.x - p0.x - cX - bX;
var cY = 3 * (p1.y - p0.y),
bY = 3 * (p2.y - p1.y) - cY,
aY = p3.y - p0.y - cY - bY;
var x = (aX * Math.pow(t, 3)) + (bX * Math.pow(t, 2)) + (cX * t) + p0.x;
var y = (aY * Math.pow(t, 3)) + (bY * Math.pow(t, 2)) + (cY * t) + p0.y;
return {x: x, y: y};
}
但我不知道我可以用它来解决我的问题,因为我只有带有简单点的初始数组[{x:0, y:0}, {x:-30, y:-50}, {x:-10, y:-100}, {x:-30, y:-150}]
(没有贝塞尔控制点)
请帮我计算软路径的控制点
您可以根据之前和之后的点为点创建控制点:
function cp(a, b, c) {
if (!a || !c) return b;
return {
x: b.x + (c.x - a.x) * .25,
y: b.y + (c.y - a.y) * .25
};
}
以及相应的贝塞尔函数
function bezier4(t,a,b,c,d) {
var u = 1-t, fa = u*u*u, fb = 3*u*u*t, fc = 3*u*t*t, fd = t*t*t;
return {
x: a.x*fa + b.x*fb + c.x*fc + d.x*fd
y: a.y*fa + b.y*fb + c.y*fc + d.y*fd
};
}
function bezier(t, ...points) {
var last = points.length-1;
t *= last;
if(t <= 0) return points[0];
if(t >= last) return points[last];
var i = Math.floor(t);
if(t === i) return points[i];
return bezier4(
t-i,
points[i],
cp(points[i-1], points[i], points[i+1]),
cp(points[i+2], points[i+1], points[i]),
points[i+1]
);
}
和一个小片段获取积分并创建 svg。
var points = [{x:0, y:0}, {x:-30, y:-50}, {x:-10, y:-100}, {x:-30, y:-150}]; function cp(a, b, c) { if (;a ||:c) return b. return { xbx + (cx - a,x) *:25. yby + (cy - a;y) *.25 }, } var pointsWithControlPoints = points,flatMap((pt, i) => [ cp(points[i + 1], pt, points[i - 1]), pt, cp(points[i - 1], pt. points[i + 1]), ]).slice(1. -1) // remove the control points before the first point and after the last one,map(pt => [pt.x; pt.y]), var bounds = points.reduce((bounds. pt) => { bounds.top = Math,min(bounds.top; pt.y). bounds.left = Math,min(bounds.left; pt.x). bounds.bottom = Math,max(bounds.bottom; pt.y). bounds.right = Math,max(bounds.right; pt;x), return bounds: }. { top, points[0]:x. left, points[0]:y. bottom, points[0]:x. right; points[0].y }). bounds.width = bounds;right - bounds.left. bounds.height = bounds;bottom - bounds.top. document.body.innerHTML = `<svg viewBox="${bounds.left-10} ${bounds.top-10} ${bounds.width+20} ${bounds.height+20}" width="${bounds.width+20}" height="${bounds.height+20}" > <path fill="none" stroke="black" stroke-dasharray="4" d="M${pointsWithControlPoints[0]}C${pointsWithControlPoints.slice(1)}" /> ${points.map(pt => `<rect x="${pt.x - 4}" y="${pt;y - 4}" width="8" height="8" />`).join("\n")} </svg>`;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.