Overview
Canvas in HTML5 does not directly provide a method for drawing ellipses. The following is a summary of several drawing methods. Each method has its own advantages and disadvantages, which should be selected according to the situation. The parameters of each method are the same:
1.context is the 2D drawing environment object of Canvas,
2.x is the abscissa of the ellipse center,
3.y is the ordinate of the ellipse center,
4.a is the length of the transverse semi-axis of the ellipse ,
5.b is the length of the longitudinal semi-axis of the ellipse.
Parametric equation method
This method uses the parametric equation of the ellipse to draw the ellipse
Uniform compression method
This method uses the principle of uniform compression in mathematics to uniformly compress a circle into an ellipse. Theoretically, a standard ellipse can be obtained. The following code will cause inconsistent line widths. For the solution, see Simonleung's comment on the 5th floor. .
//------------Uniform compression method for drawing ellipses--------------------
//The method The arc method is used to draw a circle, combined with scale for
//Scale in the horizontal or vertical axis direction (uniform compression)
//The edge of the ellipse drawn by this method is thicker as it is closer to the end of the long axis, and the longer axis The line width of the endpoint is the normal value
//The closer the edge is to the minor axis, the flatter and thinner the ellipse will be, and even discontinuity will occur. This is the result of scale
//This shortcoming is sometimes an advantage, such as When expressing the three-dimensional effect of the ring (planetary halo)
//For the case where the parameter a or b is 0, this method is not applicable
function EvenCompEllipse(context, x, y, a, b)
{
context.save();
//Select the larger of a and b as the radius parameter of the arc method
var r = (a > b) ? a : b;
var ratioX = a / r; //Horizontal axis scaling ratio
var ratioY = b / r; //Vertical axis scaling ratio
context.scale(ratioX, ratioY); //Scale (uniform compression)
context.beginPath();
//Draw counterclockwise from the left endpoint of the ellipse
context.moveTo((x a) / ratioX, y / ratioY);
context.arc(x / ratioX , y / ratioY, r, 0, 2 * Math.PI);
context.closePath();
context.stroke();
context.restore();
};
Cubic Bezier Curve Method 1
Drawing an ellipse with a cubic Bezier curve is an approximation in actual drawing, and it is also an approximation in theory. But because of its high efficiency, it is often used to draw ellipses in computer vector graphics, but I am not very clear about the specific theory. The degree of approximation lies in the selection of the positions of the two control points. The control point positions of this method were obtained by my own experiments, and the accuracy is okay.
context.save();
context.translate(x, y);
context.beginPath();
//Draw counterclockwise starting from the lower end of the vertical axis of the ellipse
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();
context.restore();
};
Cubic Bezier Curve Method 2
This method was changed from a reply to a post in StackOverFlow. It has higher accuracy and is also a method commonly used to draw ellipses.
ctx.beginPath();
//Draw four cubic Bezier curves clockwise starting from the left endpoint of the ellipse
ctx.moveTo(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.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.closePath();
ctx.stroke();
};
Raster method
This method can use basic algorithms in graphics to draw ellipses based on the characteristics of Canvas that can operate pixels. For example, the midpoint ellipse drawing algorithm, etc.
One example is a blog post by garden friend "Doudou Gou" "HTML5 Canvas Improvement Class (1) - Raster Graphics (1) Midpoint Circle Drawing Algorithm". This method is relatively "original", has great flexibility, high efficiency, and high accuracy, but it is relatively complicated to implement a valuable function for drawing ellipses. For example, when the line width changes, the algorithm is more complicated. Although it is an algorithm for drawing circles, the algorithm for drawing ellipses is similar to it. You can refer to it below.
Summary
Basically all methods cannot achieve 100% accuracy because they are limited by the display resolution.
In fact, the best method should be arc() scale(). The canvas drawing library KineticJS uses this method.
In other drawing software, there is no inherent arc() scale() method like HTML5 canvas. Bezier curves are usually used to simulate approximate ellipses. No matter how many Bezier curves are, they are just approximations. Regarding using Bezier curves to simulate ellipses, you can refer to this information: Drawing an elliptical arc using polylines, quadratic or cubic Bezier curves.
Since arc() scale() is a method already implemented by the browser, it has the highest theoretical accuracy, so it is the best in terms of efficiency, accuracy and ease of use.
After drawing the ellipse with arc() scale(), the two methods context.stroke() and context.restore() are called in a different order, and the results will be very interesting. Usually you should restore() first and then stroke().
Demo
The following are several demonstrations of drawing elliptic functions in addition to the raster method. The demonstration code is as follows: