10

Each sector can be represented as (x,y,r,a,d), where x,y is the location, r is the radius, d is the direction, and a is the angle. Given these information of two circular sectors, how to determine whether they overlap with each other? Is there any efficient algorithm for solving it? Thanks!

wzb5210
  • 735
  • 2
  • 9
  • 16
  • Don't you need _two_ angles to fully specify a circle segment? Start and end angle? – paxdiablo May 22 '12 at 01:33
  • the start angle is (d-a/2) and the end angle is (d+a/2) – wzb5210 May 22 '12 at 01:34
  • Ah, that's better. So `d` is an angle (the "centre" of the segment) and `a` is the "spread" of the segment. From the description, it looked like `d` was a simple clockwise/anticlockwise specifier. – paxdiablo May 22 '12 at 01:40
  • Worst case scenario if nobody comes up with anything else: they only intersect if one is wholly inside the other, or if their edges intersect. So you can calculate a bunch of "membership of a point in a sector" and "intersections between straight line segments and/or circular arc segments". All of which is tedious. – Steve Jessop May 22 '12 at 01:54
  • If we can determine the function that guides the given point should move where in order to get inside the sector, we can use binary search to determine if there is a common point in two sectors. I have tried a while, but no luck. Maybe three point determinant might be a good approach – batbaatar May 22 '12 at 02:58

3 Answers3

8

I know of one very quick way to discount the possibility, since I've used that for circle collisions before.

Work out the distance between the two centers and then, if that's greater than the sum of the radii, there can be no collision. For efficiency, don't use square root, just work directly on the squared values:

if (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) > (r1 + r2) * (r1 + r2):
    # No chance of collision.

Working it out for circle segments will be a little tougher.


Your choice of method depends on how accurate you need it to be. If you're doing actual math, you probably need high accuracy. But, for example, if you're doing this for something like a computer game, close enough may be good enough.

If that were the case, I'd look into transforming the arc into a series of straight lines (the number of which would probably depend on a, the "spread" of the arc - you could probably get away with a couple of lines for a spread of one degree of arc but that wouldn't work too well for 180 degrees).

Straight line collision detection is a much better known method although you have to deal with the fact that the number of comparisons may rise quickly.


If you don't want to use line segments, then here's the process to follow. It uses a circle collision algorithm to find out the zero, one or two points of collisions for the full circles, then checks those points to see if they're within both arcs.

First, run that check above to detect the case where no collision is possible. If no collision is possible between the circles, then neither can the arcs collide.

Secondly, check if the circles have a single collision point. That's the case if:

(x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) == (r1 + r2) * (r1 + r2)

within a suitable error range, of course. We should all know by now that comparing floating point numbers for equality should use some sort of delta comparison.

If that's the case, you have one point to check and you can find out that point easily. It's the point r1 units along the straight line leading from (x1,y1) to (x2,y2) or, looking at it as moving some fraction along that line:

(x1 + (x2-x1) * (r1+r2) / r1, y1 + (y2-y1) * (r1+r2) / r1)

Otherwise, there are two points to check and you can use the answers to a question like this one to establish what those two points are.

Once you have some collision points, it's a much simpler method to find out if those points are on an arc, keeping in mind that the candidate point will need to be on both arcs for them to collide, not just on one.

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • yes, string line is easier than an arc. Well, I still prefer to proving it in mathematics. Thank you very much – wzb5210 May 22 '12 at 02:05
  • Does this answer work for all cases? For example, when one sector is inside of another sector completely. Or when the arcs of two sectors do not touch, but the line segments from their "cone tips" to the "arc extremities" do touch. It seems like this answer depends on collision points along the arc. Sectors can overlap without this being the case. – Scott Lin Jun 17 '19 at 19:51
  • @Scott, I was coming from a gaming viewpoint, assuming objects were separate then crashing in to each other. You're correct that total containment would not be detected by this method. Re the 'only detecting arc collisions', I perhaps should have been clearer that the center-to-edge lines should also be checked, not just the arc-lines. I'll clear that up. – paxdiablo Jun 17 '19 at 23:08
4

There's two steps. First is to figure out if the two centres are close enough to each other to allow a collision, which can be done by comparing the distance between them to the sum of their radii:

if (((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) > ((r1 + r2) * (r1 + r2)))
    // No collision.

Then you need to check whether the line between the centres falls within the arcs defined by your various angles:

float angle1to2 = Math.atan2(y2 - y1, x2 - x1);
if (angle1to2 < (d1 - a1/2) || angle1to2 > (d1 + a1/2))
    // No collision
float angle2to1 = angle1to2 + Math.PI;
if (angle2to1 < (d2 - a2/2) || angle2to1 > (d2 + a2/2))
    // No collision

If you get through these checks without the possibility of a collision being excluded, then you have successfully detected a collision.

Caveat: this code isn't tested at all. In particular, the atan2 calls may need some tweaking depending on your coordinate system.

EDIT: just realised this misses an important corner case, where the arcs are not "pointing" at each other but still overlap. Will ruminate upon this and return...

Mac
  • 14,615
  • 9
  • 62
  • 80
  • Not sure this is right or not, but the idea is good. Thanks! I will try to think the problem in this direction – wzb5210 May 22 '12 at 02:03
  • Expanding upon my edit, I've come to realise that my approach probably doesn't work properly at all. I've got a feeling that the line between the two centres is probably not at all relevant after all - I'll get back to you if I come up with something new, but otherwise please disregard my answer for now. – Mac May 22 '12 at 02:51
1

Since we have circular sectors, angle and direction do not matter if you are doing this in real time. The following applies only to full circle sectors, or if both sectors are pointing to each other.

you can follow the next steps:

1) Find the distance between each sector, 2) Subtract both radius to that distance, 3) if the result is negative, there has been a collision between both sectors. otherwise, its the distance to collision.

for example, we have two sectors, both with a 50 unit radius. the distance between their center points is 80. subtract 80-50-50 = -20, so you know there has been a collision 20 units in distance.

otherwise, if the distance was 500, 500-50-50 = 400, a positive value, now you know that these two sectors are 400 units apart.

now, if the circles are too close, say, 1 unit apart, 1-50-50 = -99, which means they are almost totally overlapping.

For true segmented circular sectors which is what you specified on the comments, you should use paxdiablos or Macs answers.

Basilio German
  • 1,801
  • 1
  • 13
  • 22
  • That works for full circles but not necessarily for segments. Think of two ten-unit circles one unit apart. Although the circles themselves collide, segments on the outer edges (furthest from the other circle's radius) do not. – paxdiablo May 22 '12 at 01:43
  • True.but the question states circular segments, and check if they are overlapping. your answer has a good implementation by the way. – Basilio German May 22 '12 at 01:46
  • what will happen if they face in the opposite direction. Even their center points are 1 unit close, they can not overlap – wzb5210 May 22 '12 at 01:50
  • this solution is right for circle but not for sectors, right? – wzb5210 May 22 '12 at 01:52
  • true, only if the sector is a full circle. – Basilio German May 22 '12 at 01:53
  • circle is easy. how about the sectors rather than full circles – wzb5210 May 22 '12 at 01:55