I have a circle ( Striker in my game ) which moves along my 2d plane from one point to another point along a straight line. I have some other circles in the same plane which are not moving. What is the best algorithm to find the list of circles which will intersect the moving circle during its motion. If I want to code this in python what is the best approach ( Memory efficient as I want do this for lot of different states for my problem ) ?. What is the best library to be used for this purpose ?
1 Answers
You asked for an algorithm, rather than code, so here is the idea. You may want to use the math
module for this, but nothing else is really needed if you know basic American 11th grade analytic geometry.
There are two ways a stationary circle could intersect your moving circle: it could intersect with the moving circle at the start or end of its path (the red circles centered at A
and B
in the diagram below), or it could intersect the rectangle that is formed by the moving circle (the blue rectangle marked EGHF
in the diagram).
Checking intersection with the end circles is easy: circles intersect if the distance between their centers is not greater than the sum of their radii.
Checking intersection with the rectangle is a little harder. The circle at I intersects rectangle EGHF if two requirements are fulfilled. First, the center I must be between the lines GH and EF forming the ends of the rectangle. Second, the distance from I to line AB (the line enclosing the path of the moving circle's center) must be not greater than sum of the radius of the stationary circle at I and the radius of the moving circle.
An alternate, more consistent way to check intersection with the rectangle is to check to distances from the center of the stationary circle: to the perpendicular bisector (the magenta line marked p) of the start and end points of the moving circle, which must be at most half the distance between points A and B, and the distance to line AB, which must be at most the sum of the radii of the moving and stationary circles.
All those calculations (distance between two points, equations of the lines such as GH, EF, AB, and a perpendicular bisector, seeing if a point is between two parallel lines, and the distance from a point to a line) are standard in analytic geometry. Most of those calculations depend only on the moving circle--the calculations for each stationary circle are few and quick. Let me know if you need help with those formulae. There may well be a module for such formulae, but I am not aware of one.
The memory involved in this method is minimal, assuming that the radius and the start and end center coordinates of the moving circle, as well as the radius and center coordinates of the stationary circles are already in memory. If you choose my alternate approach, you could save execution time by pre-computing some values for the moving circle. If the start coordinates of the circle's center are (x1, y1) and the end coordinates are (x2, y2), you would pre-compute:
dx = x2 - x1
dy = y2 - y1
d = math.hypot(dx, dy)
det = x2 * y1 - x1 * y2
c = (x1 * x1 + y1 * y1 - x2 * x2 - y2 * y2) / 2
(Note those five values are stored only once, for the moving circle's path.) Then for each stationary circle, find the signed distance from that circle's center to the perpendicular bisector (p in my diagram), then use that to find the distance to the start circle, end circle, or line of movement. If you have many stationary circles and the path of the moving circle is small compared to the playing field, you could use a bounding rectangle for the path to quickly eliminate most of the stationary circles.

- 21,934
- 6
- 42
- 50
-
Thanks a lot for the reply. But I forgot to add one more constraint. There is a boundary line ( wall ) normal to x axis at the end point. So when the circle moves toward the point and hits the wall. So end point is not just point but a line. The circle will not pass through this line as it is obstruction. Could you please modify your answer to accomodate this ? – Bill Goldberg Nov 25 '16 at 13:34
-
That is not much of an additional constraint. If the wall is the line x=a and the radius of the moving circle is r, the circle will bump the wall at x=a-r for the circle's center. This allows you to very quickly find the y-coordinate of the stopping point of the circle's center, and you continue as in my main answer. – Rory Daulton Nov 25 '16 at 14:02
-
Will this be the memory efficient solution as I will be programing this ? Or is there any computation less approaches like using equations / calculus ? I will have to find 800*360*4 (800 starting point in all directions upto 4 intersection max) such calculations. – Bill Goldberg Nov 25 '16 at 16:55
-
I'm not sure what you mean. The memory storage is very minimal, and the execution time depends on the number of stationary circles. See the additions to my answer, if that clears some things up for you. – Rory Daulton Nov 25 '16 at 17:30
-
@BillGoldberg : This sounds like Ray-Tracing to some extend. Thus strategies from that topic can be used, most prominently the idea of (hierarchical) binning. The stationary objects get assembled in small clusters with a box or circle around them, several boxes could then be put into a bin one level higher etc. You only need to check the objects in those boxes that the ray intersects, thus vastly reducing the complexity per ray for some organizational overhead. – Lutz Lehmann Nov 26 '16 at 14:42
-
@LutzL : Could you please elaborate bit more and give me a solution which implements your idea ? – Bill Goldberg Nov 26 '16 at 16:07
-