2011-08-12 3 views

Répondre

3

Les coins peuvent être arrondis en réglant le couvre-ligne.

ctx.lineCap = "round"

Vous pouvez également appliquer une courbe de Bézier à la ligne globale de créer une ligne lisse dans l'ensemble, par, pour chaque point de la ligne P ', ..., P' n + 1 , en appliquant l'équation P » k = (k/(n + 1)) P k-1 + (1- (k/(n + 1))) P k [NB: Vous pourrait faire bien pour sélectionner les points auxquels vous appliquez le lissage de la courbe de bezier en définissant un seuil, peut-être sur l'angle entre P n et P n + 1]

La combinaison de ces deux techniques avec un flou standard boîte à la ligne elle-même vous donnera une ligne qui apparaît beaucoup plus lisse.

Modifier

D'après ce que je peux dire, il y a en fait un certain nombre de façons de le faire - que vous utilisez est entièrement à vous. Je vais vous donner un exemple, et vous laisser décider: Supposons que vous avez un chemin tracé à partir d'un point de départ p m (mousedown) à un point final (mouseup) p n. Ce chemin est composé de sous-chemins (les points joints par des mitres). Nous pouvons dessiner le chemin du contexte de p0 à p1 avec lineTo() et stroke() comme d'habitude. Juste à partir de la sortie de la console, les points auxquels les sous-chemins se rejoignent sont le tir de l'événement mousemove. Notez ces points dans l'ordre dans un tableau.

Bien sûr, si nous dessinons cela dans le contexte principal, nous avons un problème pour le supprimer, donc cela devrait être fait dans un contexte tampon (un élément canvas supplémentaire, par exemple). Le tampon est effacé et nous utilisons les points des mitres pour calculer la courbe. bezierCurveTo imprime une fonction cubique (B (t) = (1-t) P 3 (1-t) P 3 (1-t) t P + t P , t ∈ [0,1]. Etape par votre réseau (penser par boucle) recalculer la ligne avec les points, la mise à jour de la courbe P à P n-3 (Effectuez un calcul de tête rapide, vous devrez peut-être réfléchir à ce point de terminaison, tout dépend de l'équation d'arc utilisée)

Alors laissez-moi voir si je peux faire quelque chose avec ça ... Je ne suis pas en train de le tester alors je vous garantis un buggy.

// Assume: 
// bfr = buffer context. 
// ctx = main context. 
// md = boolean value for mousedown 
// pts = []; <-- already contains lp (below) at pts[0]; 
// We've also recorded Pm in associative array lp [last point] 
// Draw is fired on mousemove. Mousemove records a current point in associative array cp 
draw = function() { 
    if(md) { 
     bfr.beginPath(); 
     bfr.moveTo(lp.x-.5, lp.y-.5); 
     bfr.lineTo(cp.x-.5, cp.y-.5); 
     pts.push({cp.x, cp.y}); 
     bfr.stroke(); 
    } 
} 

// Optionally, you could make this function recursive. 
// This assumes that you want to estimate the curve based on the whole line. 
bezier = function(pts) { 
    ctx.beginPath(); 
    ctx.moveTo(pts[0].x, pts[0].y); 
    for(var i = 0; i < pts.length - 3; i++) { 
    ctx.bezierCurveTo(pts[i+1].x, pts[i+1].y, pts[i+2].x, pts[i+2].y, pts[i+3].x, pts[i+3].y); 
    } 
    ctx.stroke(); 
} 

Encore une fois, voici ce que je vois - quelqu'un d'autre peut avoir un tout autre et je suis sûr une meilleure interprétation.J'essaie de déchirer des morceaux de choses que j'ai faites et de les mettre ensemble avec un nouveau code rapidement pour vous donner une idée.

+0

Astuce sur le lineCap fonctionne. Merci. En ce qui concerne la courbe de bezier ... comment puis-je "appliquer" l'équation? Est-ce que j'utilise simplement lineTo après avoir calculé chaque point P? J'ai trouvé la fonction quadraticCurveTo et la version bezier mais celles-ci ne prennent que 3 ou 4 points d'entrée. Comment puis-je appliquer la courbe bezier à l'ensemble du coup de pinceau? – Homan

+0

J'écrirais une fonction personnalisée. Sélectionnez les points d'échantillonnage enregistrés dans un tableau, appliquez la courbe. Vous pouvez échantillonner les points auxquels le 'mousemove' se déclenche, déterminer l'angle entre trois points pour vérifier s'il s'agit d'une différence significative pour un point d'échantillonnage, le signaler s'il l'est, puis l'utiliser pour appliquer une courbe. Je passerais le tableau des points marqués à la fonction pour effectuer l'évaluation. Commencez toujours avec 'mousedown' et' mouseup' comme 0 et n + 1. – stslavik

+0

Supposons que l'utilisateur dessine un cercle rapide, mais que les points d'échantillon sont répartis plus comme les coins d'un octogone. Vous suggérez de "courber" la ligne en utilisant une sorte de fonction personnalisée bezierLine (sample_points) à droite? Je ne comprends pas ce qui se passe dans cette fonction? La fonction dessine-t-elle chaque pixel en calculant chaque coordonnée de pixel? Ou est-ce que la fonction prend un paramètre d'étape t pour la traversée de Bézier (t), auquel cas la fonction trace toujours une ligne en utilisant lineTo, non? – Homan

Questions connexes