Dessiner une flèche / vecteur dans canvas
avec la bonne orientation !
Dans l'élément canvas de html5, on peut facilement tracer des lignes et des polygones. Pour tracer des flèches au bout de ces lignes, ou des vecteurs, il faut réfléchir un peu…
Ci-dessous une fonction qui permet de tracer des vecteurs ou des flèches.
La fonction Vecteur(xA,yA,xB,yB,ArrowLength,ArrowWidth) détaillée ci-dessous trace le vecteur , c'est-à-dire le segment ainsi que la flèche au point orientée convenablement.
Les paramètres sont
- et : les coordonnées de l'origine
- et : les coordonnées de l'extrémité
- ArrowLength et ArrowWidth: deux paramètres optionnels et qui désignent deux paramètres de taille pour le dessin de la flèche, tel que représenté ci-dessous:
Pour les impatients ou les personnes allergiques au calcul, vectoriel entre autre, ou encore qui n'éprouvent pas le besoin de comprendre le fonctionnement d'une telle fonction (et qui ne pensent donc pas non plus avoir besoin de l'adapter un jour à une autre fin un peu différente), le code complet et son illustration se trouve un peu plus bas.
Un peu d'analyse vectorielle permet de déterminer simplement les coordonnées des points C, D et E.
Tous les détails sur le calcul vectoriel se trouvent et pour le produit scalaire: .
Coordonnées du point C
Les vecteurs et sont colinéaires de même sens, le vecteur étant de plus unitaire (de longueur, ou norme, égale à 1).
La fonction Norm(xA,yA,xB,yB) calcule et retourne justement la longueur .
On a ainsi , ce qui s'écrit en termes de coordonnées:
soit encore,
Coordonnées du point D
Les droites et sont perpendiculaires; en d'autres termes, plus efficaces pour mener des calculs analytiques, les vecteurs et sont orthogonaux.
(pour lequel on vérifie bien simplement que le produit scalaire ).
Ainsi, comme de plus le vecteur et on a la même norme: , et de plus on a , soit, en termes de coordonnées:
soit encore,
Coordonnées du point E
De même que pour le point D, on a: , soit en termes de coordonnées:
Représentation graphique Une fois les coordonnées de ces points calculées, il ne reste plus qu'à tracer, en commençant par ctx.beginPath(); puis,
- le segment : ctx.moveTo(xA,yA);ctx.lineTo(xB,yB);
- la flèche : ctx.moveTo(xD,yD);ctx.lineTo(xB,yB);ctx.lineTo(xE,yE);
<canvas id="canvas" width="300" height="200" ></canvas>
<script>
Width=document.getElementById("canvas").width;
Height=document.getElementById("canvas").height;
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
function Norm(xA,yA,xB,yB) {
return Math.sqrt(Math.pow(xB-xA,2)+Math.pow(yB-yA,2));
}
function Vecteur (xA,yA,xB,yB,ArrowLength,ArrowWidth) {
if (ArrowLength === undefined) {ArrowLength=10;}
if (ArrowWidth === undefined) {ArrowWidth=8;}
ctx.lineCap="round";
// Calculs des coordonnées des points C, D et E
AB=Norm(xA,yA,xB,yB);
xC=xB+ArrowLength*(xA-xB)/AB;yC=yB+ArrowLength*(yA-yB)/AB;
xD=xC+ArrowWidth*(-(yB-yA))/AB;yD=yC+ArrowWidth*((xB-xA))/AB;
xE=xC-ArrowWidth*(-(yB-yA))/AB;yE=yC-ArrowWidth*((xB-xA))/AB;
// et on trace le segment [AB], et sa flèche:
ctx.beginPath();
ctx.moveTo(xA,yA);ctx.lineTo(xB,yB);
ctx.moveTo(xD,yD);ctx.lineTo(xB,yB);ctx.lineTo(xE,yE);
ctx.stroke();
}
// Et 3 exemples d'utilisation:
ctx.strokeStyle="red";
Vecteur(30,180,120,150);
ctx.strokeStyle="blue";
ctx.lineWidth=4;
ArrowLength=10;ArrowWidth=8;
Vecteur(200,100,30,25,ArrowLength,ArrowWidth);
ctx.strokeStyle="green";
ctx.lineWidth=2;
ArrowLength=6;ArrowWidth=4;
for (i=0;i<15;i++) {
Vecteur(240,30+10*i,260,20+10*i,ArrowLength,ArrowWidth);
}
</script>
Voir aussi: