1
\$\begingroup\$

Major Edit

I'm making a Breakout clone, and having difficulty with collision detection between a circle and line segment.

Apologies, my earlier question was a result of frustration and no sleep :)

Having read this post on collision detection I've re-written my collision code to the following:

    // Takes 2 points on a line, a circle centre, and a circle radius
    // Returns true is collision, false otherwise
    public Boolean DoesCollide(Vector2 a, Vector2 b, Vector2 c, float rad)
    {
        // First up, let's normalise our vectors so the circle is on the origin
        Vector2 normA = a - c;
        Vector2 normB = b - c;

        Vector2 d = normB - normA;

        // Want to solve as a quadratic equation, need 'a','b','c' components
        float aa = Vector2.Dot(d, d);
        float bb = 2 * (Vector2.Dot(normA, d));
        float cc = Vector2.Dot(normA,normA)-(rad*rad);

        // Get determinant to see if LINE intersects
        double deter = Math.Pow(bb, 2.0) - 4 * aa * cc;
        if (deter > 0)
        {
            // Get t values (solve equation) to see if LINE SEGMENT intersects
            double t = (-bb - Math.Sqrt(deter)) / (2 * aa);
            double t2 = (-bb + Math.Sqrt(deter)) / (2 * aa);
            Boolean match = false;

            if (0.0 <= t && t <= 1.0)
            {
                // Interpolate to get collision point
                Vector2 collisionPoint = c + Vector2.Lerp(normA, normB, (float)t);          
                match = true;
            }
            if (0.0 <= t2 && t2 <= 1.0)
            { 
                Vector2 collisionPoint2 = c + Vector2.Lerp(normA, normB, (float)t2);
                match = true;
            }
            return match;
        }
        else
            return false;
    } 

However, I'm getting strange results for the X components of the collision points found 'on hit' - see the following debug output:

Coll at {X:1033.931 Y:620}, t1 = 0.203759334390812, Normalised = {X:0.8576241    Y:0.5142772}
Coll2 at {X:1052.069 Y:620}, t2 = 0.409877029245551, Normalised = {X:0.8615275 Y:0.5077109}
Circ cent = {X:1043 Y:610}, rad = 13.5

As you can see, the X components are 10px either side of the circle centre, but the Y component (620) is the very topmost pixel of the top of the Breakout paddle. Surely here the X points can't be 20 pixels apart, given the location of the Y point?

\$\endgroup\$
6
  • \$\begingroup\$ can you please add some comments to your code? what are a,b,c vectors? and what does aa,bb,cc represent? \$\endgroup\$
    – Ali1S232
    Oct 12, 2011 at 6:25
  • \$\begingroup\$ Did you check my answer here? gamedev.stackexchange.com/questions/18333/… I explain how the algorithm works in a simple way, this is generally better than try to adapt a code you don't fully understand \$\endgroup\$
    – FxIII
    Oct 12, 2011 at 6:52
  • \$\begingroup\$ Apologies all, I posed this at 3am and was very frustrated. Will look at FxIII's algorithm :) \$\endgroup\$ Oct 12, 2011 at 10:25
  • \$\begingroup\$ @FxIII I've read through your post and written a method to solve for t as per your post. However, I'm getting some odd results - I've updated my question above. Could you assist? \$\endgroup\$ Oct 12, 2011 at 11:32
  • \$\begingroup\$ @FxIII, sorry - updated now :) \$\endgroup\$ Oct 12, 2011 at 11:42

1 Answer 1

2
\$\begingroup\$

You are missing a stage before calculating t0 and t1. It should look more like this:

float q; // Holds the solution to the quadratic equation
if (bb >= 0)
{
   q = (-bb - Math.Sqrt(deter)) / 2;
}
else
{
   q = (-bb + Math.Sqrt(deter)) / 2;
}

float t0 = q / aa;
float t1 = cc / q;

After that, make sure t0 and t1 are sorted. [Edit] I made a small error with the determinant signs, note they are now reversed.

\$\endgroup\$
5
  • \$\begingroup\$ thanks for answering. How do you mean 'sorted' (in reference to t1 / t0)? \$\endgroup\$ Oct 12, 2011 at 12:48
  • \$\begingroup\$ This kind of solution sounds new to me. I'm try to figure out its correctness... \$\endgroup\$
    – FxIII
    Oct 12, 2011 at 12:49
  • \$\begingroup\$ Checkt t0 is smaller than t1, and if they are not, swap them. \$\endgroup\$ Oct 12, 2011 at 13:32
  • \$\begingroup\$ What is the case here if t1 and t0 are exactly equal, yet less than 0? Determ is positive. \$\endgroup\$ Oct 15, 2011 at 13:58
  • \$\begingroup\$ Also, otherwise this seems to be working a treat. Thanks to FxIII also, will upvote when I've enough rep. \$\endgroup\$ Oct 16, 2011 at 14:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .