2

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);
JSmith
  • 4,519
  • 4
  • 29
  • 45
  • i don't know the algorithm, but one idea would be to group your coords differenlty, something like `var coords = [ [ ] ]; ` and then you should have `coords[x][y] = value;` When you will check if the the line was already drew, you will just have an `if (coords[x][y] == value) *line already drew *` – lessan Jul 16 '18 at 14:18
  • This is one way of thinking about the problem. this means for a circle of radius 50 to allocate an array of 100 * 100. I'll think about it but that doesn't solve my second problem. Thx anyway that's a good point of view – JSmith Jul 16 '18 at 14:25
  • I answered this in 3d over here: https://stackoverflow.com/questions/41656006/how-to-rasterize-a-sphere/41666156#41666156 – Matt Timmermans Jul 16 '18 at 14:31
  • Hi Matt I would be delighted if you'd answer for the 2D case. Plus you'll get more reputation points if your answer is correct. I'm not really good at math so 2D for me is hard so in 3D is even worst. Thanks for your comprehension. – JSmith Jul 16 '18 at 14:38
  • You are calling `coords = drawCircle(xc, yc, x, y, coords);` twice per loop ! –  Jul 16 '18 at 14:47
  • @YvesDaoust but your totally right I've just deleted the line. I should defenitly have noticed it before. Thanks again – JSmith Jul 16 '18 at 15:17

0 Answers0