简体   繁体   中英

Given a few points and circles, how can I tell which point lies in which circles?

Given a small number of points and circles (say under 100), how do I tell which point lies in which circles? The circles can intersect, so one point can lie in multiple circles.

If it's of any relevance, both points and circle centers are aligned on a hexagonal grid, and the radii of the circles are also aligned to the grid.

With a bit of thought, it seems the worse case scenario would always be quadratic (when each point lies in all circles) ... but there might be some way to make this faster for the average case when there aren't that many intersections?

I'm doing this for an AI simulation and the circle/point locations change all the time, so I can't really pre-compute anything ahead of time.

If the number of points and circles is that small, you probably will get away with brute-forcing it. Circle-point intersections are pretty cheap, and 100 * 100 checks a frame shouldn't harm performance at all.

If you are completely sure that this routine is the bottleneck and needs to be optimized, read on.

You can try using a variation of Bounding Volume Hierarchies .

A bounding volume hierarchy is a tree in which each node covers the entire volume of both (or more if you decide to use a tree with higher degree) of its children. The volumes/objects that have to be tested for intersections are always the leaf nodes of the tree.

Insertion, removal and intersection queries have an amortized average run-time of O(log n) . You will however have to update the tree, as your objects are dynamic, which is done by removing and reinserting invalid nodes (nodes which do not contain their leaf nodes fully any more). Updating the full tree takes a worst case time of O(n log n) .

Care should be taken that while insertion, a node should be inserted into that sub-tree that increases the sub-tree's volume by the least amount.

Here is a good blog post by Randy Gaul which explains dynamic bounding hierarchies well.

You'll have to use circles as the bounding volumes, unless you can find a way to use AABBs in all nodes except leaf nodes, and circles as leaf nodes. AABBs are more accurate and should give you a slightly better constructed tree.

You can build a kd-tree of the points. And then for each circle center you retrieve all the points of the kd-tree with distance bounded by the circle radius. Given M points and N circles the complexity should be M log M + N log M = max(M,N) log M (if points and circles are "well distributed").

Whether you can gain anything compared to a brute-force pair-wise check depends on the geometric structure of your points and circles. If, for instance, the radii of the circles are big in relation to the distances of the points or the distances of the cirlce centers then there is not much to expect, I think.

Rather than going to a full 2D-tree, there is an intermediate possibility based on sorting.

Sort the P points on the abscissas. With a good sorting algorithm (say Heapsort), the cost can be modeled as SPLg(P) (S is the cost of comparisons/moves).

Then, for every circle (C of them), locate its leftmost point (Xc-R) in the sorted list by dichotomy, with a cost D.Lg(P) (D is the cost of a dichotomy step). Then step to the rightmost point (Xc+R) and perform the point/circle test every time.

Doing this, you will spare the comparisons with the points to the left and to the right of the circle. Let F denote the average fraction of the points which fall in the range [Xc-R, Xc+R] for all circles.

Denoting K the cost of a point/circle comparison, the total can be estimated as

SPLg(P) + D.Lg(P).C + FKPC

to be compared to KPC

The ratio is

S/K.Lg(P)/C + D/K.Lg(P)/P + F.

With the unfavorable hypothesis that S=D=K, for P=C=100 we get 6.6% + 6.6% + F. These three terms respectively correspond to the preprocessing time, an acceleration overhead and the reduced workload.

Assuming resonably small circles, let F = 10%, and you can hope a speedup x4.


If you are using a bounding box test before the exact point/circle comparison (which is not necessarily an improvement), you can simplify the bounding box test to two Y comparisons, as the X overlap is implicit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM