Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Circle to Circle Segment Collision

I'm struggling to find a rock solid solution to detecting collisions between a circle and a circle segment. Imagine a Field of View cone for a game enemy, with the circles representing objects of interest.

The diagram at the bottom is something I drew to try and work out some possible cases, but i'm sure there are more.

I understand how to quickly exlude extreme cases, I discard any targets that don't collide with the entire circle, and any cases where the center of the main circle is within the target circle are automatically true (E in the diagram).

I'm struggling to find a good way to check the rest of the cases. I've tried comparing distances between circle centers and the end points of the segments outer lines, and i've tried working out the angle of the center of the target circle from the center of the main circle and determining whether that is within the segment, but neither way seems to catch all cases.

Specifically it seems to go funky if the target circle is close to the center but not touching it (somewhere between E and B below), or if the segment is narrower than the target circle (so that the center is within the segment but both edges are outside it).

Is there a reliable method for doing this?

Extra info: The segment is described by position P, orientation O (whose magnitude is the circle radius), and a view size, S.

My most successful attempt to date involved determining the angles of the vectors ca1 and ca2, and checking if either of them lies between the angles of vectors a1 and a2. This works for some cases as explained above, but not situations where the target circle is larger than the segment.

Edit 2 After implementing the best suggestion from below, there is still a false positive which I am unsure how best to eliminate. See the pink diagram below. The circle in the lower right is reporting as colliding with the segment because it's bounds overlap both half spaces and the main circle.

collision typescurrent solution

false positiveedge case


Final Edit

After discovering another edge case (4th image), i've settled on an approach which combines the two top answers from below and seems to cover all bases. I'll describe it here for the sake of those who follow.

First exclude anything that fails a quick circle-to-circle test.

Then test for collision between the circle and the two outer lines of the segment. If it touches either, return true.

Finally, do a couple of point-to-halfspace tests using the center of the circle and the two outer lines (as described by Gareth below). If it passes both of those it's in, otherwise return false.

like image 283
beeglebug Avatar asked Nov 19 '10 15:11

beeglebug


People also ask

How do you find a collision between circles?

Determining whether or not two circles intersect or overlap is the most basic way of determining whether or not two circles have collided. This is done by comparing the distance squared between the two circles to the radius squared between the two circles.

How do you know if a line segment intersects a circle?

To determine the position of a line with respect to a circle, all we need to do is find its distance from the center of the circle, and compare it with its radius. Then, if the distance is less than the radius, the line must intersect the circle at two distinct points.

How do you find the collision between a rectangle and a circle?

Case 1: The side of the rectangle touches or intersects the circle. In order to check whether the shapes intersect, we need to find a point on or inside the rectangle that is closest to the center of the circle. If this point lies on or inside the circle, it is guaranteed that both the shapes intersect.

Does line intersect circle?

In geometry, a line meeting a circle in exactly one point is known as a tangent line, while a line meeting a circle in exactly two points in known as a secant line (Rhoad et al. 1984, p. 429).


1 Answers

A. Check if it is intersecting the whole cirlce.
B. Check if it is intersecting either of the straight segment lines.
C. If not, check if the angle between the circle centres lies in the angular range of the segment (dot product is good for this).

Intersection requires A && (B || C)

like image 98
Peter Alexander Avatar answered Oct 27 '22 00:10

Peter Alexander