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:
context is the 2D drawing environment object of Canvas,
x is the abscissa of the ellipse center,
y is the ordinate of the ellipse center,
a is the length of the transverse semi-axis of the ellipse,
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
//----------Use parametric equations to draw ellipses---------------- -----
//The parameters x and y of the function are the center of the ellipse; a, b are the transverse semi-axis and the length of the vertical semi-axis of the ellipse respectively, which cannot be 0 at the same time
//This The disadvantage of the method is that when linWidth is wider and the ellipse is flatter
//The long axis end inside the ellipse is sharper, not smooth, and the efficiency is low
function ParamEllipse(context, x, y, a, b)
{
//max is equal to 1 divided by the larger of the major axis values a and b
//i increases by 1/max each loop, indicating an increase in degrees
//This works Make the path (arc) drawn in each cycle close to 1 pixel
var step = (a > b) ? 1 / a : 1 / b;
context.beginPath();
context. moveTo(x a, y); //Start drawing from the left endpoint of the ellipse
for (var i = 0; i < 2 * Math.PI; i = step)
{
//Parametric equation is x = a * cos(i), y = b * sin(i),
//The parameter is i, indicating the degree (radians)
context.lineTo(x a * Math.cos(i), y b * Math.sin(i));
}
context.closePath();
context.stroke();
};
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 the problem of inconsistent line widths. See 5 for the solution. Lou simonleung's comment.
//------ -----Uniform compression method to draw an ellipse--------------------
//The method is to use the arc method to draw a circle and combine it with scale
//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 line width at the end of the long axis is the normal value
//Side The closer it is to the minor axis, the flatter and thinner the ellipse will be, and even discontinuities, which is the result of scale
//This shortcoming is sometimes an advantage, such as when expressing the three-dimensional effect of a ring (planetary halo)
//For the case where 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); //scaling (uniform compression)
context.beginPath();
// Draw counterclockwise starting 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 Er curve method 1
Cubic Bezier curve drawing ellipse 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 position of this method was obtained by my own experiments, and the accuracy is okay.
//---------Use cubic Bezier curve to simulate ellipse 1---------------------
//This method will also produce the phenomenon that when the lineWidth is wider and the ellipse is flatter,
//the long axis end is sharper and not smooth
function BezierEllipse1(context, x, y, a, b )
{
//The key is the setting of the two control points in bezierCurveTo
//0.5 and 0.6 are the two key coefficients (obtained from experiments in this function)
var ox = 0.5 * a,
oy = 0.6 * b;
context.save();
context.translate(x, y);
context.beginPath();
//From ellipse vertical The lower end of the axis starts to draw counterclockwise
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.
//--------- Use cubic Bezier curve to simulate ellipse 2---------------------
//This method will also produce when lineWidth is wider and the ellipse is flatter
//, the long axis end is sharp and not smooth
//This method is more accurate than the previous Bezier method, but slightly less efficient
function BezierEllipse2(ctx, x, y, a, b)
{
var k = .5522848,
ox = a * k, // Horizontal control point offset
oy = b * k; // Vertical control point offset Quantity
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 operate pixels according to the Canvas Features, using basic algorithms in graphics to draw ellipses. 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.
Demo
The following are several demonstrations of drawing elliptic functions in addition to the raster method. The demonstration code is as follows:
Note that to successfully run the code, a browser that supports HTML5 Canvas is required.
Writing a blog for the first time took me a whole day, it was not easy! The dark skin template of Blog Park does not display well for the inserted code. I took great pains to figure out the code format!