Présentation Canvas en HTML5 ne fournit pas directement de méthode pour dessiner des ellipses. Ce qui suit est un résumé de plusieurs méthodes de dessin. Chaque méthode a ses propres avantages et inconvénients, qu’il convient de choisir en fonction de la situation. Les paramètres de chaque méthode sont les mêmes :
context est l'objet d'environnement de dessin 2D de Canvas,
x est l'abscisse du centre de l'ellipse,
y est l'ordonnée du centre de l'ellipse,
a est la longueur du demi-axe transversal de l'ellipse,
b est la longueur du demi-axe longitudinal de l'ellipse.
Méthode d'équation paramétrique Cette méthode utilise l'équation paramétrique de l'ellipse pour dessiner l'ellipse
//----------Utiliser des équations paramétriques pour dessiner des ellipses---------- ------ -----
//Les paramètres x et y de la fonction sont le centre de l'ellipse a, b sont le demi-axe transversal et la longueur du demi-axe vertical de ; l'ellipse respectivement, qui ne peut pas être 0 en même temps
//Ceci L'inconvénient de la méthode est que lorsque linWidth est plus large et que l'ellipse est plus plate
//L'extrémité de l'axe long à l'intérieur de l'ellipse est plus nette, pas lisse et l'efficacité est faible
fonction ParamEllipse(context, x, y, a, b)
{
//max est égal à 1 divisé par la plus grande des valeurs des grands axes a et b
//i augmente de 1/max à chaque boucle, indiquant une augmentation en degrés
//Cela fonctionne Faites en sorte que le chemin (arc) tracé dans chaque cycle soit proche de 1 pixel
var step = (a > ; b) ? 1 / a : 1 / b;
context.beginPath();
context.(x a, y); //Commencer à dessiner à partir de l'extrémité gauche de l'ellipse
for (var i = 0; i < 2 * Math.PI; i = étape)
{
//L'équation paramétrique est x = a * cos(i), y = b * sin(i),
//Le paramètre est i, indiquant le degré (radians)
context.lineTo(x a * Math.cos(i), y b * Math.sin(i)
}
context.closePath( );
context.stroke();
};
Méthode de compression uniforme
Cette méthode utilise le principe de compression uniforme en mathématiques pour compresser uniformément un cercle en ellipse. Théoriquement, une ellipse standard peut être obtenue. Le code suivant provoquera le problème des largeurs de ligne incohérentes. Voir 5 pour le commentaire de Lou Simonleung.
//---- -----Méthode de compression uniforme pour dessiner une ellipse-------------------
//La méthode consiste à utiliser la méthode de l'arc pour dessiner une cercle et combinez-le avec l'échelle
//Échelle dans la direction de l'axe horizontal ou vertical (compression uniforme)
//Le bord de l'ellipse dessinée par cette méthode est plus épais car il est plus proche de l'extrémité de l'axe long , et la largeur du trait à l'extrémité de l'axe long est la valeur normale
//Côté Plus elle est proche de l'axe mineur, plus l'ellipse sera plate et fine, et même les discontinuités, ce qui est le résultat de l'échelle
//Ce défaut est parfois un avantage, comme pour exprimer l'effet tridimensionnel d'un anneau (halo planétaire)
//Pour le cas où le paramètre a ou b vaut 0, cette méthode n'est pas applicable
function EvenCompEllipse(context, x, y, a, b)
{
context.save();
//Sélectionnez le plus grand de a et b comme paramètre de rayon de la méthode arc
var r = (a > b) ? a : b;
var ratioX = a / r; //Rapport de mise à l'échelle de l'axe horizontal
var ratioY = b / r; context.scale(ratioX, ratioY); //mise à l'échelle (compression uniforme)
context.beginPath();
// Dessinez dans le sens inverse des aiguilles d'une montre en partant de l'extrémité gauche de l'ellipse
context.moveTo((x a) / ratioX, y / ratioY);
context.arc(x / ratioX, y / ratioY, r, 0, 2 * Math. PI
context.closePath(); );
context.restore();
};
Méthode 1 de la courbe Er de Bézier cubique
L'ellipse de dessin de la courbe de Bézier cubique est une approximation en réalité dessin, et c'est aussi une approximation en théorie. Mais en raison de sa grande efficacité, il est souvent utilisé pour dessiner des ellipses en infographie vectorielle, mais je ne suis pas très clair sur la théorie spécifique. Le degré de rapprochement réside dans le choix des positions des deux points de contrôle. La position du point de contrôle de cette méthode a été obtenue par mes propres expériences, et la précision est correcte
//Cette méthode produira également le phénomène selon lequel lorsque la largeur de ligne est plus large et l'ellipse est plus plate,
//l'extrémité de l'axe long est plus nette et non lisse
fonction BezierEllipse1(contexte , x, y, a, b )
{
//La clé est le réglage des deux points de contrôle dans bezierCurveTo
//0,5 et 0,6 sont les deux coefficients clés (obtenus à partir d'expériences dans cette fonction )
var ox = 0.5 * a,
oy = 0.6 * b;
context.save();
context.translate(x, y>
context.beginPath();
//De l'ellipse verticale L'extrémité inférieure de l'axe commence à dessiner dans le sens inverse des aiguilles d'une montre
context.moveTo(0, b);
context.bezierCurveTo(ox, b, a, oy, a, 0);
context.bezierCurveTo(a, -oy , ox, -b, 0, -b);
context.bezierCurveTo(-ox, -b, -a, -oy, -a, 0); >context.bezierCurveTo(-a, oy, - ox, b, 0, b);
context.closePath();
context.stroke(); };
Méthode de courbe de Bézier cubique 2 Cette méthode a été modifiée à partir d'une réponse à un message dans StackOverFlow. Elle a une plus grande précision et est également une méthode couramment utilisée pour dessiner des ellipses. >
//--------- Utilisez la courbe de Bézier cubique pour simuler l'ellipse 2 ---------------------
//Cette méthode produira également lorsque lineWidth est plus large et que l'ellipse est plus plate
//, l'extrémité de l'axe long est pointue et non lisse
//Cette méthode est plus précise que la méthode Bézier précédente, mais légèrement moins efficace
fonction BezierEllipse2(ctx, x, y, a, b)
{
var k = .5522848,
ox = a * k, // Décalage du point de contrôle horizontal
oy = b * k; // Décalage du point de contrôle vertical Quantité
ctx.beginPath( );
//Dessinez quatre courbes de Bézier cubiques dans le sens des aiguilles d'une montre en partant de l'extrémité gauche de l'ellipse
ctx.moveTo(x - a, y);
ctx.bezierCurveTo (x - a, y - oy,); x - boeuf, y - b, x, y - b);
ctx.bezierCurveTo(x ox, y - b, x a, y - oy, x a, y);
ctx.bezierCurveTo(x a, y); oy, x ox, y b, x, y b);
ctx.bezierCurveTo(x - ox, y b, x - a, y oy, x - a, y); >ctx.stroke();
};
Méthode raster
Cette méthode peut exploiter les pixels selon les fonctionnalités du canevas, en utilisant des algorithmes de base dans les graphiques pour dessiner des ellipses. Par exemple, l'algorithme de dessin d'ellipse médiane, etc.
Un exemple est un article de blog de l'ami jardinier "Doudou Gou" "Classe d'amélioration du canevas HTML5 (1) - Graphiques raster (1) Algorithme de dessin de cercle médian". Cette méthode est relativement « originale », présente une grande flexibilité, une grande efficacité et une grande précision, mais elle est relativement compliquée à mettre en œuvre une fonction précieuse pour dessiner des ellipses. Par exemple, lorsque la largeur du trait change, l’algorithme est plus compliqué. Bien qu'il s'agisse d'un algorithme pour dessiner des cercles, l'algorithme pour dessiner des ellipses lui est similaire. Vous pouvez vous y référer ci-dessous.
Démo Voici plusieurs démonstrations de dessin de fonctions elliptiques en plus de la méthode raster. Le code de démonstration est le suivant :
Copier le code.