[英]How to code an nth order Bezier curve
嘗試在畫布上的 javascript 中為項目編寫 n 階貝塞爾曲線。 我希望能夠讓用戶按下一個按鈕,在本例中為“b”,以選擇每個端點和控制點。 到目前為止,我能夠在按鍵上獲取鼠標坐標,並使用內置函數制作二次曲線和貝塞爾曲線。 我將如何為 n 階編寫代碼?
這是n階貝塞爾曲線的Javascript實現:
// setup canvas var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); canvas.height = window.innerHeight; canvas.width = window.innerWidth; ctx.fillText("INSTRUCTIONS: Press the 'b' key to add points to your curve. Press the 'c' key to clear all points and start over.", 20, 20); // initialize points list var plist = []; // track mouse movements var mouseX; var mouseY; document.addEventListener("mousemove", function(e) { mouseX = e.clientX; mouseY = e.clientY; }); // from: http://rosettacode.org/wiki/Evaluate_binomial_coefficients#JavaScript function binom(n, k) { var coeff = 1; for (var i = n - k + 1; i <= n; i++) coeff *= i; for (var i = 1; i <= k; i++) coeff /= i; return coeff; } // based on: https://stackoverflow.com/questions/16227300 function bezier(t, plist) { var order = plist.length - 1; var y = 0; var x = 0; for (i = 0; i <= order; i++) { x = x + (binom(order, i) * Math.pow((1 - t), (order - i)) * Math.pow(t, i) * (plist[i].x)); y = y + (binom(order, i) * Math.pow((1 - t), (order - i)) * Math.pow(t, i) * (plist[i].y)); } return { x: x, y: y }; } // draw the Bezier curve function draw(plist) { ctx.clearRect(0, 0, canvas.width, canvas.height); var accuracy = 0.01; //this'll give the 100 bezier segments ctx.beginPath(); ctx.moveTo(plist[0].x, plist[0].y); for (p in plist) { ctx.fillText(p, plist[p].x + 5, plist[p].y - 5); ctx.fillRect(plist[p].x - 5, plist[p].y - 5, 10, 10); } for (var i = 0; i < 1; i += accuracy) { var p = bezier(i, plist); ctx.lineTo(px, py); } ctx.stroke(); ctx.closePath(); } // listen for keypress document.addEventListener("keydown", function(e) { switch (e.keyCode) { case 66: // b key plist.push({ x: mouseX, y: mouseY }); break; case 67: // c key plist = []; break; } draw(plist); });
html, body { height: 100%; margin: 0 auto; }
<canvas id="canvas"></canvas>
這是基於三次貝塞爾曲線的這種實現 。 在您的應用程序中,聽起來您需要使用用戶定義的點填充points
組。
這是您要添加以制作貝塞爾曲線的任意數量的點的代碼示例。 您將傳遞的點是一個包含點的 x 和 y 值的對象數組。 [ { x: 1,y: 2 } , { x: 3,y: 4} ... ]
function factorial(n) {
if(n<0)
return(-1); /*Wrong value*/
if(n==0)
return(1); /*Terminating condition*/
else
{
return(n*factorial(n-1));
}
}
function nCr(n,r) {
return( factorial(n) / ( factorial(r) * factorial(n-r) ) );
}
function BezierCurve(points) {
let n=points.length;
let curvepoints=[];
for(let u=0; u <= 1 ; u += 0.0001 ){
let p={x:0,y:0};
for(let i=0 ; i<n ; i++){
let B=nCr(n-1,i)*Math.pow((1-u),(n-1)-i)*Math.pow(u,i);
let px=points[i].x*B;
let py=points[i].y*B;
p.x+=px;
p.y+=py;
}
curvepoints.push(p);
}
return curvepoints;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.