Quick collision detection to insert a circle into a 2D plane

I know that there are many collision detection messages, usually for sprites moving around a 2D plane, but my question is slightly different.

I insert circles into a 2D plane. Circles have variable radii. I am trying to optimize my method of finding a random position in a plane, where I can insert a new circle without interfering with other circles already on the plane. Now I use a very “not optimized” approach, which simply generates a random point inside the plane and then checks it on all other circles on the plane.

Are there any ways to optimize this? For this particular application, the borders of the plane can hold only 20-25 circles at a time, and usually they are from 5 to 10. As you would expect, when the number of circles approaches the maximum that can fit, you need to check a lot of points before finding one that works. This is very slow.

Note: safeDistance is the radius of the circle that I want to add to the plane.

Here is the code:

- (CGPoint)getSafePosition:(float)safeDistance {
// Point must be far enough from edges
// Point must be far enough from other sprites

CGPoint thePoint;
BOOL pointIsSafe = NO;

int sd = ceil(safeDistance);

while(!pointIsSafe) {

    self.pointsTested++; // DEBUG

    // generate a random point inside the plane boundaries to test
    thePoint = CGPointMake((arc4random() % ((int)self.manager.gameView.frame.size.width - sd*2)) + sd, 
                           (arc4random() % ((int)self.manager.gameView.frame.size.height - sd*2)) + sd);

    if(self.manager.gameView.sprites.count > 0) {
        for(BasicSprite *theSprite in self.manager.gameView.sprites) {

            // get distance between test point and the sprite position
            float distance = [BasicSprite distanceBetweenPoints:thePoint b:theSprite.position];

            // check if distance is less than the sum of the min safe distances of the two entities
            if(distance < (safeDistance + [theSprite minSafeDistance])) {
                // point not safe
                pointIsSafe = NO;
                break;
            }

            // if we get here, the point did not collide with the last tested point
            pointIsSafe = YES;
        }
    }
    else {
        pointIsSafe = YES;
    }
}

return thePoint;
}
+3
source share
4 answers

w h. w by h, dist. dist[x][y] , (x, y). ( , , .)

dist[x][y] min(x, y, w - x, h - y). , , .

, , , (a, b) r, dist.

, (x, y):

dist[x][y] = min(dist[x][y], sqrt((x - a)^2 + (y - b)^2) - r);

(, ^2 , XOR.) : " dist [x] [y] , , ". dist , .

, q, dist dist >= q. ( , , .)

+3

, 20-25 , fancier (, quadtree kd-tree). n.

, ? ? , , , - , . while, ?

+2

( quadtree) , . , "" ( - ).

.

0

, .

, , , . C. , , C. D ( C), C, D. . , , , , . 360 C, , C, , C. , C, , .

0
source

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


All Articles