Finding all the points within a circle in 2D space

I am representing my 2D space (consider a window), where each pixel is shown as a cell in a 2D array. ie a 100x100 window is represented by the array of same dimensions.

Now given a point in the window, if I draw a circle of radius r , I want to find all the points lying in that circle.

I was thinking I'd check for the each point in the square region around the radius, with side = 2*r , if it lies in the circle or not. I'll use the normal distance formula maybe?

Hence, maybe the following:

for (x=center-radius ; x<center+radius ; x++){
    for (y=center-radius ; y<center+radius; y++) {
        if (inside) {
            // Do something
        }
    }
}

Will it serve my purpose? Can I make it faster?


Will it serve my purpose?

For your 100x100, yes.

Can I make it faster?

Yes. For example, you can:

  • Check only 1 quadrant and get other points because of symmetry.
  • Skip the square root when calculating the distance.
  • Code:

    for (x = xCenter - radius ; x <= xCenter; x++)
    {
        for (y = yCenter - radius ; y <= yCenter; y++)
        {
            // we don't have to take the square root, it's slow
            if ((x - xCenter)*(x - xCenter) + (y - yCenter)*(y - yCenter) <= r*r) 
            {
                xSym = xCenter - (x - xCenter);
                ySym = yCenter - (y - yCenter);
                // (x, y), (x, ySym), (xSym , y), (xSym, ySym) are in the circle
            }
        }
    }
    

    That's about 4x speed up.

    JS tests for solutions presented here. Symmetry is the fastest on my computer. Trigonometry presented by Niet the Dark Absol is very clever, but it involves expensive mathematical functions like sin and acos , which have a negative impact on performance.


    You can bypass the need for a conditional check:

    for(x=center-radius; x<center+radius; x++) {
        yspan = radius*sin(acos((center-x)/radius));
        for(y=center-yspan; y<center+yspan; y++) {
            // (x,y) is inside the circle
        }
    }
    

    If needed, you can round(yspan) .


    You can get speed ups by computing as much outside of the loops as possible. Also there's no need to do the Pythagoras Theorem square root... just keep everything squared. One final speed-up can be made by only doing the math for one quarter of the circle (because it's symmetrical)... when a match is found you just replicate it for the other three quarters.

    radiusSquared = radius*radius;
    rightEdge = centerX+radius;
    bottomEdge = centerY+radius;
    for(x = centerX; x <= rightEdge; x++){
        xSquared = x*x;
        for(y = centerY; y <= bottomEdge; y++){
            ySquared = y*y;
            distSquared = xSquared+ySquared;
            if(distSquared <= radiusSquared){
                // Get positions for the other quadrants.
                otherX = centerX-(x-centerX);
                otherY = centerY-(y-centerY);
                // Do something for all four quadrants.
                doSomething(x, y);
                doSomething(x, otherY);
                doSomething(otherX, y);
                doSomething(otherX, otherY);
            }
        }
    }
    
    链接地址: http://www.djcxy.com/p/84938.html

    上一篇: 网格点算法(在网格中查找点)

    下一篇: 在二维空间中查找圆内的所有点