Simple Sphere-Sphere Collision Detection and Collision Response

Collision Detection

To determine if two spheres are colliding, we take the sum of the radiuses and compare it with the length from the centers of the spheres. If the lenght is smaller than the sum of the radiuses, we have a collision.

Difference vector (the length is the distance between those two spheres):
vec{d} = s1.pos - s2.pos

Then the length is computed:
distance = vec{d}.length = sqrt{vec{d}.x^2 + vec{d}.y^2 + vec{d}.z^2}

Sum of the radiuses:
sumradius = s1.radius + s2.radius

If distance<sumradius the we have a collision to take care of.

Collision Response

This is the little more trickier part, but with some basics explained, it should be pretty straight forward.

First, find the vector which will serve as a basis vector (x-axis), in an arbiary direction. It have to be normalized to get realistic results.
vec{x} = s1.pos - s2.pos
vec{x}.normalize()

Then we calculate the x-direction velocity vector and the perpendicular y-vector.
vec{v1} = s1.vel
x1 = x.dot(vec{v1})
vec{v1x} = vec{x} * x1
vec{v1y} = vec{v1} - vec{v1x}
m1 = s1.mass

Same procedure for the other sphere.
vec{x} = vec{x}*-1
vec{v2} = s2.vel
x2 = vec{x}.dot(vec{v2})
vec{v2x} = vec{x} * x2
vec{v2y} = vec{v2} - vec{v2x}
m2 = s2.mass

Then we mix and play around with some of Newtons laws to obtain a formula for the speed (in vector format) after the collision.
s1.vel = vec{v1x}{(m1-m2)/(m1+m2)} + vec{v2x}{(2*m2)/(m1+m2)} + vec{v1y}
s2.vel = vec{v1x}{(2*m1)/(m1+m2)} + vec{v2x}{(m2-m1)/(m1+m2)} + vec{v2y}

And it actually works! :)

Sample application:

Source code in subversion repository.

VN:F [1.9.13_1145]
Rating: 5.0/5 (3 votes cast)
Simple Sphere-Sphere Collision Detection and Collision Response, 5.0 out of 5 based on 3 ratings
Share

17 Comments

  1. Marco says

    I was looking for a clear tutorial on collision response and i found it here.
    great post, very usefull!

    Thanks

  2. Jonas says

    I had to refresh my dusty brain, and this was perfect for that!

    Thanks!

  3. Edgar says

    This information was very usefull in a demo that i’m trying to build in XNA. Thanks

  4. Niklas Rother says

    I tried to adapt this in C#/XNA, but it seems that there is a mistake: x is a Vector3 (Vector with 3 Components) and v1 also. So x.dot(v1) is a float (scalar/normal number). But in the line you use the Cross product (or am I wrong?), and you can´t make a Crossproduct of a Vector3 (x) and a float (x1).
    Additional the SVN link seems down, so I couldt check the code…

  5. kent says

    Niklas: I think it should be “vector multiplied by a scalar”, not cross product.

    This goes without checking the code, which I’ll do later when I fix the repository.

  6. kent says

    @Niklas

    I have fixed the websvn interface (and svn interface).

  7. Nick Wiggill says

    This doesn’t actually appear to work when one of the circle-bodies is stationary — it will not impart any forces in this instance, at least in my use of this code.

  8. Nick Wiggill says

    No — ignore my prior comment — I am mistaken. There is something other bug in my application of your code.

  9. Nick Wiggill says

    I had issues with my vector rotation code. Your approach works fine. Many thanks.

  10. kent says

    @Nick

    I’m glad you found this useful!

    Thanks.

  11. Robert says

    Super! All I need to to calculate the two angles that describe how to draw the line between sphere centers.. Can you help me there? How do I correctly write the code to get the two angles?

  12. Chris says

    A very nice tutorial for the collision response between two spheres. Unfortunately it doesn’t hold up when more than two spheres can collide at once.

    Although I suppose the solution for that is seperate to this tutorial as you just figure out which collision occurs first in the current frame and then push the physics simulation back and forwards through the frame until all collisions have been resolved.

  13. Elena says

    Hi,

    This helped a lot! I have been tormenting myself with books and other theoretical stuff for four days now and without any results. I still have a question. Does this work even when one object is stationary?

  14. Julian says

    Thanks! I’ve been looking for a nice and clear tut and i finally found it! You’re awesome!

  15. pw says

    great stuff. have converted this to c# xna with little much to change. x.dot() is vector3.dot(x,v1) and the final 2 lines omit the vector3 bracket: s1.Velocity = v1x…blah;

  16. aram says

    hi
    i’m trying to write code of a game named peggle,maby you know it.
    now i want to have collision functoin in my code & i hope you help me for that problem.
    if it is possible for you send methis code as E-mail;
    thank you…….!!!!!!!!

  17. kent says

    aram: you can see the source code in subversion repository (link at the end of the article)

Leave a Reply

Leave a Reply
  • (required)
  • (required) (will not be published)