Dans Canvas, vous pouvez facilement dessiner un cercle à l'aide de la méthode d'arc. À l'origine, le cercle peut également être considéré comme une ellipse avec une largeur et une hauteur égales, mais il n'y a aucun moyen de dessiner une ellipse en toile. Nous devons utiliser d'autres méthodes pour la simuler.
Tout d'abord, nous devons clarifier les paramètres nécessaires pour dessiner une ellipse. Les connaissances géométriques de base nous indiquent que l'ellipse a besoin des coordonnées centrales, de la largeur, de la hauteur ou de l'angle de rotation, mais cela peut être évité pour le moment, la rotation est relativement facile.
1. Utilisez Lineto pour dessiner une ellipse Vous lisez ce bien, Lineto, une méthode qui est purement utilisée pour dessiner des lignes droites, peut réellement être utilisée pour dessiner des ellipses! ? Mais il existe, mais le style d'écriture est vraiment incroyable:fonction drawellipse (canvas, o, oa, ob) {
// dessine une ellipse, exemple: var b = nouveau tableau (150 150); Drawellipse (HB, B, 50,30);
avec (canvas) {
var x = o [0] + oa;
var y = o [1];
MoveTo (x, y);
pour (var i = 0; i <= 360; i ++) {
var ii = i * math.pi / 180;
var x = o [0] + oa * math.cos (ii);
var y = o [1] -ob * math.sin (ii);
lineto (x, y);
}
}
}
Le principe de cette méthode est qu'un cercle a 360 degrés, alors utilisez LineTo pour faire bouger 360 fois, dessiner les segments de ligne de chaque degré et enfin les connecter dans une ellipse. Parmi eux, la fonction trigonométrique sinusité doit être utilisée pour le calcul.
Notez que le deuxième paramètre de cette méthode est un tableau, c'est-à-dire que les coordonnées centrales de l'ellipse.
L'idée est très étrange et l'ellipse dessinée est relativement lisse. Mais il ne vaut pas la peine d'être utilisé - cette méthode nécessite 360 cycles pour chaque ellipse dessinée. Ce n'est que lorsque l'ellipse est dessinée est un moindre test des performances du navigateur.
Nous avons juste besoin de comprendre ses idées
2. Utilisez l'arc pour dessiner un cercle et l'échellez-vous dans une ellipse Le texte d'origine de cette méthode est ici, et la fonction centrale est la suivante:var canvas = document.getElementById ('myCanvas');
var context = canvas.getContext ('2d');
var CenterX = 0;
Var Centery = 0;
Var Radius = 50;
// Économiser l'état
context.save ();
// Traduire le contexte
context.translate (canvas.width / 2, canvas.height / 2);
// Échelle le contexte horizontalement
context.scale (2, 1);
// dessiner un cercle qui sera étiré dans un ovale
context.beginPath ();
context.arc (CenterX, Centery, Radius, 0, 2 * Math.pi, false);
// Restaurer à l'état d'origine
context.Restore ()
Cette méthode utilise une fonction de toile que je n'ai pas mentionnée auparavant, c'est-à-dire l'échelle, qui peut réaliser la mise à l'échelle de la toile. La mise à l'échelle a deux directions: horizontale et verticale. Le code élargit la direction horizontale de la toile, tandis que la direction verticale reste inchangée. Ainsi, le cercle dessiné par l'arc se transforme en ellipse.
Cette méthode est très merveilleuse à première vue, avec peu de codes, et les principes sont simples et faciles à comprendre. Mais après l'avoir analysé, vous trouverez ses lacunes évidentes, c'est-à-dire qu'elle est - inexacte! Par exemple, j'ai besoin d'une ellipse de 171 de large et de 56 de haut. Si nous définissons le rayon de l'arc sur 28, le nombre suivant de 171/28/2 sera déprimé.
Cependant, il existe une méthode de compromis pour toujours régler le rayon de l'arc à 100, puis, si ce n'est pas suffisant, il sera agrandi, et s'il le dépasse, il sera réduit. Cependant, il est toujours inexact.
3. Utilisez Bezier Curveto Comme j'ai senti que la méthode de mise à l'échelle ci-dessus est inexacte, je veux vraiment trouver une méthode exacte pour dessiner des ellipses, et je l'ai finalement trouvé sur StackOverflow:fonction drawellipse (ctx, x, y, w, h) {
var kappa = 0,5522848;
ox = (w / 2) * kappa, // point de contrôle décalage horizontal
Oy = (H / 2) * Kappa, // Point de contrôle Offset vertical
xe = x + w, // x-end
ye = y + h, // y-end
xm = x + w / 2, // x-middle
ym = y + h / 2; // Y-Middle
ctx.beginPath ();
ctx.moveto (x, ym);
ctx.beziercurveto (x, ym - oy, xm - ox, y, xm, y);
ctx.beziercurveto (xm + ox, y, xe, ym - oy, xe, ym);
ctx.beziercurveto (XE, ym + oy, xm + ox, ye, xm, ye);
ctx.beziercurveto (xm - ox, ye, x, ym + oy, x, ym);
ctx.closepath ();
ctx.stroke ();
}
Cette méthode peut être considérée comme parfaite. Il a divisé une ellipse en 4 courbes de Bezier et les a connectées à une ellipse. La largeur et la hauteur finales sont également relativement précises et les frais généraux sont moindres.
Mais cette méthode a encore ses inconvénients. Tout le monde regarde le paramètre Kappa et il y a une valeur très étrange. Je crois que beaucoup de gens ne comprennent pas pourquoi ils doivent prendre cette valeur avant que l'expert en géométrie ne vous dise pourquoi ils veulent prendre cette valeur - je ne le sais toujours pas. Et j'avais une forte envie de le changer et de voir quelles étaient les conséquences.
Bien sûr, mon impulsion similaire aux patients atteints de troubles obsessionnels-compulsives ne peut être considéré comme l'inconvénient de cette méthode. Son vrai inconvénient est - pourquoi avez-vous besoin d'utiliser 4 courbes de Bezier? Je pense personnellement qu'une ellipse est évidemment composée de deux courbes de Bezier plutôt que de quatre. Cette idée m'a finalement amené à trouver le moyen le plus parfait de dessiner une ellipse.
4. Utilisez deux courbes à aspect pour dessiner une ellipse
Afin de comprendre si la méthode précédente peut être rationalisée, j'ai spécialement enregistré un compte StackOverflow pour poser des questions. Puisqu'il y a des images dans la question, les points ne peuvent pas être transmis. J'ai dû utiliser ma compétence à peine anglaise pour répondre aux questions des étrangers pour gagner des points. Mais à la fin, bonne chance, et répondre à une question a résolu mon problème de points.
J'ai soulevé le problème de la relation entre la courbe de Besel et l'ellipse.
Pour être honnête, je ne comprenais pas la plupart des réponses des étrangers ci-dessous, mais heureusement, il a fourni un exemple de page de code, ce qui m'a fait comprendre le principe, et je voudrais le remercier encore. Selon sa réponse, la méthode que j'ai trouvée pour dessiner des ellipses est la suivante:
//ovale
CanvasRenderingContext2d.prototype.oval = fonction (x, y, largeur, hauteur) {
var k = (largeur / 0,75) / 2,
w = largeur / 2,
H = hauteur / 2;
this.beginPath ();
this.moveto (x, yh);
this.BezierCurveto (x + k, yh, x + k, y + h, x, y + h);
this.BezierCurveto (xk, y + h, xk, yh, x, yh);
this.closepath ();
retourner ceci;
}
Cette méthode est à la fois précise et a peu de code, et il n'y a pas d'étrange et difficile à comprendre. N'oubliez pas cela, le rapport de coordonnées de la largeur de l'ellipse au point de contrôle de la courbe de Besel qui tire l'ellipse est le suivant:
Le point de contrôle de Bessel x = (largeur d'ellipse / 0,75) / 2 est déjà reflété dans le code.
Vous pouvez tester les quatre méthodes ci-dessus pour dessiner une ellipse.
Si vous trouvez un moyen plus facile, veuillez le partager et en discuter.