help working out if 2 spheres overlap / colided

Started by
4 comments, last by Dmytry 19 years, 3 months ago
i have been looking on gamasutra,at the sphere on sphere sweep tests, but i cant figure out the code, partly as its in c++ ( i only know c#) and 2nd that im not fantastic at maths. can anyone explain better how i can work out if spheres have colided?
I currently only use c# and directX9, in case its relivant and i didnt mention it in the post
Advertisement
Moved to "Math and physics".

Quote:can anyone explain better how i can work out if spheres have colided?

Maybe I'm over simplifying it, but given a center and radius for each sphere, the following logic is all thats needed:

1. Calculate the distance between the two center points:
dist = square_root( a*a + b*b + c*c )
where:
- a = (sphere1_x - sphere2_x)
- b = (sphere1_y - sphere2_y)
- c = (sphere1_z - sphere2_z)


2. if the distance is GREATER THAN the sum of the two radii then the spheres are not touching/intersecting

3. if the distance is EQUAL TO the sum of the two radii they are just touching on the surfaces.

4. if the distance is LESS THEN the sum of the two radii they are intersecting/overlapping each other.

I'm sure you can convert that into relatively simple C# code [grin]

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

I think he's asking about a swept test, not static intersection.

What part of the code/algorithm are you having trouble with? The algorithm is fairly straightforward and involves solving a quadratic equation to find the first time, if any, of contact between the spheres. If you can tell us what you're uncertain about, someone here will be able to clarify things for you.
Quote:I think he's asking about a swept test, not static intersection.

oops! my bad... thought it sounded a bit too simple - I usually don't get my hands dirty in M&P for this reason [grin]..

Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

It is easy enough to see that sweep sphere test is the same as ray-sphere intersection. Let one sphere is stationary, other is moving along some ray. Let radiuses is r1,r2 respectively. Then, spheres collide when distance between centers <r1+r2 . Same as intersection of ray with sphere that have radius r1+r2.

If both spheres is moving, you need to do everything relatively to one of spheres.

I have posted my ray-sphere intersection code to this forum about 7 times.
//// Ray-sphere intersection.// p=(ray origin position - sphere position),// d=ray direction,// r=sphere radius,// Output:// i1=first intersection distance,// i2=second intersection distance// i1<=i2// i1>=0// returns true if intersection found,false otherwise.//bool RaySphereIntersect(const Vec3 &p, const Vec3 &d,double r, double &i1, double &i2){        double det,b;        b = -DotProduct(p,d);        det=(b*b) - DotProduct(p,p) + r*r;        if (det<0){                return false;        }        det= sqrt(det);        i1= b - det;        i2= b + det;        // intersecting with ray?        if(i2<0) return false;        if(i1<0)i1=0;        return true;};

note that direction must be normalized.
If you call this with
// doing everything relatively to first sphere
Vec3 V=Velocity2-Velocity1;
double l=Length(V);
V*=1/l;
double i1,i2
... RaySphereIntersect(Position2-Position1,V,radius1+radius2,i1,i2);
i1/=l;
you'll get i1=time of first collision. i1=0 if already collided.

You can optimize code if you like. I think, that
// // Warning: Non-tested function.//// Ray-sphere intersection that works as moving point-sphere collision.// p=(point start position - sphere center position),// v=point velocity,// r=sphere radius,// Output:// i1=first intersection time,// i2=second intersection time// i1<=i2// i1>=0// returns true if intersection found,false otherwise.//bool RaySphereIntersectTime(const Vec3 &p, const Vec3 &v,double r, double &i1, double &i2){        double det,b,k;        k = DotProduct(v,v);          b = -DotProduct(p,v)/k;                det=b*b - (DotProduct(p,p) - r*r)/k;        if (det<0){                return false;        }        det= sqrt(det);        i1= b - det;        i2= b + det;        // intersecting with ray?        if(i2<0) return false;        if(i1<0)i1=0;        return true;};

if(RaySphereIntersectTime(Position2-Position1,Velocity2-Velocity1,radius1+radius2,i1,i2)){
i1=time of first collision. i1=0 if already collided.
};

P.S. for Nth time, DotProduct(d,d) or DotProduct(p,p) is not a typo.

This topic is closed to new replies.

Advertisement