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;
            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?

  • \$\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 '11 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 '11 at 6:52
  • \$\begingroup\$ Apologies all, I posed this at 3am and was very frustrated. Will look at FxIII's algorithm :) \$\endgroup\$ Oct 12 '11 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 '11 at 11:32
  • \$\begingroup\$ @FxIII, sorry - updated now :) \$\endgroup\$ Oct 12 '11 at 11:42

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;
   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.

  • \$\begingroup\$ thanks for answering. How do you mean 'sorted' (in reference to t1 / t0)? \$\endgroup\$ Oct 12 '11 at 12:48
  • \$\begingroup\$ This kind of solution sounds new to me. I'm try to figure out its correctness... \$\endgroup\$
    – FxIII
    Oct 12 '11 at 12:49
  • \$\begingroup\$ Checkt t0 is smaller than t1, and if they are not, swap them. \$\endgroup\$ Oct 12 '11 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 '11 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 '11 at 14:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.