簡體   English   中英

如何編碼 n 階貝塞爾曲線

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM