Looking for advice on arc/point collision detection

Posted by (twitter: @Eliot_L)
April 21st, 2012 11:29 pm

I’d appreciate some advice on whether my collison system can be salvaged or if I need to rewrite it.
My game is using polar coordinates and I am defining sections of arcs like so for the level geometry:

Right now I wrote checks to see if a point at polar coordinate (r, theta) is inside the region between the greater and lesser arc that makes up a solid object, like so:

class Arc {
  //Not a true arc, more of a segment of one or a "Block Arc", but it's much easier to type.
  float startAngle;
  float stopAngle;
  float maxRadius;
  float minRadius;
  boolean collidesWith(PolarCoord point) {
    return !( startAngle > point.t ||
              stopAngle < point.t ||
              minRadius > point.r ||
              maxRadius < point.r );

(Full class is here.)

It appears my math doesn’t work out for arcs on certain intervals. Previously I had encountered issues with this code not working when a radian was less than 0 or greater than 2*pi, so I wrapped my radians between 0 and 2*pi which fixed it. But I need to define some arcs that start around, say, the radian equivalent of ~270 degrees and end at ~45 degrees, making the shape of the letter C and crossing the 0 degrees mark. This kind of arc breaks my collision check above.

So I’m thinking, I can either fix my math for the check somehow, or abandon this method completely. Unfortunately I can’t find many resources on how to do this type of collision check properly. I couldn’t even find what these arc segment shapes are actually called.

In addition, I’m seeing occasional tunneling issues and would like to switch to doing an arc segment + line segment test for continuous collision instead of just an arc/point test.

The alternative I thought of was to define my arcs based on a vector at the center and an angle, and use the dot product to the player to do my collison checks, similar to the FOV check described here.

But it will take time to do that and I’d rather salvage this code if possible. If anyone has any advice, please let me know.

Tags: , ,

4 Responses to “Looking for advice on arc/point collision detection”

  1. steamgirl says:

    Not really my strong suit, so not sure if it’s any help, but couldn’t you do a workaround for arcs that break that? Eg, if it’s more than # degrees, use a circle collision detection and deduct the remaining shape or something like that? Hopefully someone else will have a better answer… but it seems a shame to ditch it all-together.

  2. Jacob says:

    It will help to try and split the check up as much as possible, then the solution becomes more obvious.
    If I’m reading this right you could do:

    1) Check that the distance is correct
    — eg: minRadius < actualRadius < maxRadius
    2) check that the angle is correct
    — eg: that the angle is some number just to the right of the left angle, AND just to the left of the right angle.
    — eg: the angular-distance from the left edge TO the angle is positive AND the angular-distance from the angle to the right edge is positive

    Hopefully that haaaalps.

  3. DiThi says:

    I would do this: define an arc always with the first angle lower than the second, AND a boolean to define if it goes first->second or second->first (inverted). Just do the angle check and invert the result with the “invert” boolean. If you want to do that only when detecting the collision without changing the rest of the code, it would be somethin like this:
    invert = first>second
    point_is_in_angle = min(first,second) < point.t < max(first,second)
    point_is_in_angle ^= invert

    Hope it helps.

  4. Eliot says:

    Thanks for the suggestions. I had two people respond on twitter telling me to just split the arc into two arcs along the axis, so I did that so I could move on to coding the rest of the game. I will definitely keep these suggestions in mind if I run into bugs, or have time to go back and clean things up, but the upshot is collision is more or less working now!

Leave a Reply

You must be logged in to post a comment.

[cache: storing page]