I use Bresenham's circle algorithm. But I've noticed as you will see by yourself by running the code below that this algorithm draws sometimes multiple times the same pixel.
What I usually do is parse all the anterior coordinates to check if it hasn't been drawn already to avoid drawing twice at the same place. This works but I know this is slowing down the whole process.
When this is done I also get another problem when I use drawLine(x1, y1, x2, y2)
function instead of putPixel(x, y)
to fill my circle. Sometimes the top and the bottom have something like 3 lines of the different width at the same y
coordinate. for example I get a top first line of coordinates
(20, 10, 24, 10)
then a second line
(21, 10, 23, 10)
and a third
(22, 10, 22, 10) (a simple pixel)
Any clue(s) how I can solve these problems?
function circleBres(xc, yc, r)
{
var x = 0, y = r;
var d = 3 - 2 * r;
var coords = [];
while (y >= x)
{
coords = drawCircle(xc, yc, x, y, coords);
x++;
if (d > 0)
{
y--;
d = d + 4 * (x - y) + 10;
}
else
d = d + 4 * x + 6;
}
nbOccurs(coords);
}
function drawCircle(xc, yc, x, y, coords)
{
coords = addCoords(xc+x, yc+y, coords);
coords = addCoords(xc-x, yc+y, coords);
coords = addCoords(xc+x, yc-y, coords);
coords = addCoords(xc-x, yc-y, coords);
coords = addCoords(xc+y, yc+x, coords);
coords = addCoords(xc-y, yc+x, coords);
coords = addCoords(xc+y, yc-x, coords);
coords = addCoords(xc-y, yc-x, coords);
return (coords)
}
function addCoords(x, y, coords)
{
coords.push({x:x, y:y, parsed: false});
return (coords)
}
function nbOccurs(coords)
{
var i = 0
var results = [];
while(i < coords.length)
{
var nbOccur = 1;
var j = 0;
while (j < coords.length)
{
while (coords[j].parsed && j < coords.length - 1)
j++;
if (coords[i].x === coords[j].x && coords[i].y && coords[j].y)
{
nbOccur++;
coords[j].parsed = true;
}
j++;
}
if (nbOccur == 1)
console.log("x:" + coords[i].x + " " + "y:" + coords[i].y + " is drawn " + nbOccur + " time");
else
console.log("x:" + coords[i].x + " " + "y:" + coords[i].y + " is drawn " + nbOccur + " times");
i++;
}
}
circleBres(50, 50, 25);