HTML5 very large canvas circle fuzzy

I am developing an application in which users draw Euclidean constructs on HTML5 canvas. Therefore, I can not limit the size of certain shapes. When exaploring very large circles are drawn on the screen, I noticed that very large circles do not have a constant radius.

To be more specific, the circle defined by two points, the center point and the one defining the radius no longer pass through the radius point!

Large circle with radius point

Progressively large circles. All must pass through point E.

Larger circles

An error does not occur at the edges of 45 degrees = PI / 4. Between these multiples the largest error (e.g. PI / 8)

Here is the jsfiddle containing the first example above:

http://jsfiddle.net/D28J2/2/

My questions: Why is this happening? and is there a way (effectively) to get around this?

+6
source share
4 answers

The way I worked on this problem completely reduced my own implementation of the circular curve approximation using Bezier curves. Detailed implementation information can be found here http://www.tinaja.com/glib/ellipse4.pdf .

function magic_circle(ctx, x, y, r){ m = 0.551784 ctx.save() ctx.translate(x, y) ctx.scale(r, r) ctx.beginPath() ctx.moveTo(1, 0) ctx.bezierCurveTo(1, -m, m, -1, 0, -1) ctx.bezierCurveTo(-m, -1, -1, -m, -1, 0) ctx.bezierCurveTo(-1, m, -m, 1, 0, 1) ctx.bezierCurveTo( m, 1, 1, m, 1, 0) ctx.closePath() ctx.restore() } 

Only with these four segments was I able to get closer to the circle much better than building google chrome canvas implementations.

+3
source

This is probably a floating point cutoff error. Perhaps because the sine and cosine do not give absolutely exact values. You can get around it (at least in Chrome) by rotating the canvas instead of the arc.

 ctx.save(); // Save the canvas so we can rotate back. ctx.translate(x, y); // Translate to the origin point. ctx.rotate(alpha); // Rotate the proper angle. ctx.arc(0, 0, 3, 0, Math.PI*2); // Draw the small circle at the origin. ctx.fill(); ctx.arc(r, 0, r, 0, Math.PI*2); // Create a big with the origin 1 radius away. ctx.restore(); // Restore the canvas to the original orientation // before drawing. Otherwise the circle looks bad. ctx.strokeStyle = "black"; ctx.stroke(); // Draw! 

I am a big fan of manipulating canvas instead of shapes. This gives you a more logical area to work. See http://jsfiddle.net/D28J2/10/

+2
source

Just throw it away, but could it be a problem without specifying enough PI digits? Whenever I do such things, I lean a little overboard and use about 10 digits of PI.

+1
source

In Google chrome, I can repeat the problem, but in IE 9 and IE 10 everything is fine.

Therefore, I assume that the implementation is incorrect in Chrome. This may be a rounding error, or they used the interpolation method to avoid sin and cos, which is not very high.

See also: HTML5 canvas arches do not display correctly in Google Chrome

The only work I can imagine is to draw a circle using my own code or use a plugin (jQuery?) That does this for you.

0
source

Source: https://habr.com/ru/post/904997/


All Articles