2015-07-01 11 views
5

Próba kodowania beziera beziera w javascript na płótnie dla projektu. Chcę, aby użytkownik mógł nacisnąć przycisk, w tym przypadku "b", aby wybrać każdy punkt końcowy i punkty kontrolne. Do tej pory jestem w stanie uzyskać współrzędne myszy przy naciśnięciu klawisza i tworzyć krzywe kwadratowe i beziera za pomocą wbudowanych funkcji. W jaki sposób chciałbym wykonać kod dla n-tego rzędu?Jak zakodować n-tego rzędu Krzywa Beziera

+0

Utwórz tablicę i zapisz każdą linię w niej. – user2072826

Odpowiedz

5

Oto realizacji JavaScript nth porządkowych krzywych Beziera:

// 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(p.x, p.y); 
 
    } 
 

 
    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>

ta opiera się na this implementation of cubic Bezier curves. W twojej aplikacji brzmi to tak, jakbyś chciał wypełnić tablicę points punktami zdefiniowanymi przez użytkownika.

+0

Dziękuję. Pytanie uzupełniające: jaki jest najlepszy sposób dodawania punktów zdefiniowanych przez użytkownika? Eksperymentowałem przez ostatni dzień, ale nie wymyśliłem niczego, co działa. Chcę tylko, aby użytkownik nacisnął "b", a następnie narysuje po każdym naciśnięciu, aby dwukrotnie nacisnąć "b" dla linii, 3 dla kwadratu itd. – Adam

+2

[Tutaj jest skrzypce] (http: // jsfiddle .net/rphv/3jkt16Ly/3 /), które mogą pomóc. Dodaje nowy punkt pod wskaźnikiem myszy po naciśnięciu klawisza "b" i czyści listę punktów po naciśnięciu "c". Wyświetla również punkty (numbererd), gdy są dodawane. Aby to zrobić, odświeżyłem kod rysunku do jego własnej funkcji 'draw()', przeniosłem 'plist' do zasięgu globalnego i dodałem detektor' mousemove' do śledzenia pozycji myszy. Proszę rozważyć umieszczenie powyższej odpowiedzi, jeśli to pomogło. – rphv

+0

Dziękuję bardzo! Chciałbym przegłosować, gdybym mógł, ale nie pozwoli mi jeszcze powód rep. Moje konto jest bardzo nowe – Adam