# Circle drawing alternatives

## JavaScript performance comparison

Test case created by Timo

## Preparation code

``````

<script>
Benchmark.prototype.setup = function() {
var PI2=Math.PI*2;

function drawpixel(x,y)
{
return;
}
};

</script>
``````

## Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
sqrt
``````var r=50, dia, refX, refY, refOrigoDist;
for(var dia=0;dia<4;dia=dia+0.03)
{

refX = (dia < 2 ? 1-dia : dia-3);
refY = (dia < 3 ? ((dia > 1) ? 2-dia : dia) : dia-4);
refOrigoDist = Math.sqrt(refX*refX + refY*refY);
drawpixel( 50 + r * refX / refOrigoDist,
50 + r * refY / refOrigoDist);
}``````
pending…
cos sin
``````var r=50, point;
for(var i=0;i<PI2;i=i+0.05)
{
drawpixel(50 + Math.cos(i) * r, 50 + Math.sin(i) * r);
}``````
pending…
Incremental
``````var xm=50, ym=50, r=50;
var x = -r, y = 0, err = 2-2*r; /* II. Quadrant */
do {
drawpixel(xm-x, ym+y); /*   I. Quadrant */
drawpixel(xm-y, ym-x); /*  II. Quadrant */
drawpixel(xm+x, ym-y); /* III. Quadrant */
drawpixel(xm+y, ym+x); /*  IV. Quadrant */

r = err;
if (r <= y) {
++y;
err += y*2+1;           /* e_xy+e_y < 0 */
}
if (r > x || err > y)
{
++x;
err += x*2+1; /* e_xy+e_x > 0 or no 2nd y-step */
}
} while (x < 0);``````
pending…
Precalculate trigs
``````var cx=50, cy=50, px=0, py=50, theta=PI2, N=125, point;

var dx = px - cx;
var dy = py - cy;
var r2 = dx * dx + dy * dy;
var r = Math.sqrt(r2);
var ctheta = Math.cos(theta/(N-1));
var stheta = Math.sin(theta/(N-1));
drawpixel(cx + dx, cy + dy);
for(var i = 1; i != N; ++i)
{
var dxtemp = ctheta * dx - stheta * dy;
dy = stheta * dx + ctheta * dy;
dx = dxtemp;
drawpixel(cx + dx, cy + dy);
}
``````
pending…
CircleBresenham
``````//http://willperone.net/Code/codecircle.php
var xc=50, yc=50, r=50;

var x = 0,
y = r,
p = 3 - 2 * r;
while (y >= x) // only formulate 1/8 of circle
{
drawpixel(xc-x, yc-y);//upper left left
drawpixel(xc-y, yc-x);//upper upper left
drawpixel(xc+y, yc-x);//upper upper right
drawpixel(xc+x, yc-y);//upper right right
drawpixel(xc-x, yc+y);//lower left left
drawpixel(xc-y, yc+x);//lower lower left
drawpixel(xc+y, yc+x);//lower lower right
drawpixel(xc+x, yc+y);//lower right right
if (p < 0) p += 4*x++ + 6;
else p += 4*(x++ - y--) + 10;
}``````
pending…
CircleMidpoint
``````//http://willperone.net/Code/codecircle.php
var xc=50, yc=50, r=50;

var   x= 0, y= r, d= 1-r, dE= 3, dSE= 5 - 2*r;
drawpixel(xc-r, yc);
drawpixel(xc+r, yc);
drawpixel(xc, yc-r);
drawpixel(xc, yc+r);

while (y > x)    //only formulate 1/8 of circle
{
if (d < 0)
{
d+= dE;
dE+=2, dSE+=2;
} else {
d+=dSE;
dE+=2, dSE+=4;
y--;
}
x++;

drawpixel(xc-x, yc-y);//upper left left
drawpixel(xc-y, yc-x);//upper upper left
drawpixel(xc+y, yc-x);//upper upper right
drawpixel(xc+x, yc-y);//upper right right
drawpixel(xc-x, yc+y);//lower left left
drawpixel(xc-y, yc+x);//lower lower left
drawpixel(xc+y, yc+x);//lower lower right
drawpixel(xc+x, yc+y);//lower right right
}
``````
pending…
CircleOptimized
``````//http://willperone.net/Code/codecircle.php
var xc=50, yc=50, r=50;

var x= r, y= 0, cd2= 0;
drawpixel(xc-r, yc);
drawpixel(xc+r, yc);
drawpixel(xc, yc-r);
drawpixel(xc, yc+r);

while (x > y)    //only formulate 1/8 of circle
{
cd2-= (--x) - (++y);
if (cd2 < 0) cd2+=x++;

drawpixel(xc-x, yc-y);//upper left left
drawpixel(xc-y, yc-x);//upper upper left
drawpixel(xc+y, yc-x);//upper upper right
drawpixel(xc+x, yc-y);//upper right right
drawpixel(xc-x, yc+y);//lower left left
drawpixel(xc-y, yc+x);//lower lower left
drawpixel(xc+y, yc+x);//lower lower right
drawpixel(xc+x, yc+y);//lower right right
} ``````
pending…
DrawCircle
``````// http://slabode.exofire.net/circle_draw.shtml
var cx=50, cy=50, r=50, num_segments=125;

var theta = 2 * 3.1415926 / num_segments,
tangetial_factor = Math.tan(theta), //calculate the tangential factor

radial_factor = Math.cos(theta), //calculate the radial factor

x = r, //we start at angle = 0
y = 0, tx, ty, ii;

for(ii = 0; ii < num_segments; ii++)
{
drawpixel(x + cx, y + cy); //output vertex

//calculate the tangential vector
//remember, the radial vector is (x, y)
//to get the tangential vector we flip those coordinates and negate one of them

tx = -y;
ty = x;

//add the tangential vector

x += tx * tangetial_factor;
y += ty * tangetial_factor;

//correct using the radial factor

} ``````
pending…

## Revisions

You can edit these tests or add even more tests to this page by appending `/edit` to the URL.

# 1 Comment

Will Perone commented :

Hah just found this; glad to see that my optimized circle algorithm is indeed optimized :)