Acurate Response to Sphere-Sphere Intersection

Started by
16 comments, last by aleks_1661 20 years, 3 months ago
sorry, I misunderstood the problem.

That would happens when the time of collision is slightly negative. in that case, if ''c'' is less than 0.0f in the equation, the spheres are overlapping, and the time calculation will return something < 0.0f.

So, if ''c'' < 0.0f, catch it as an overlap collision, and push the spheres apart, so sphere2 is at the surface of sphere1.

float overlap_depth = r - O.Magnitude();
Vector OverlapNormal = O / O.Magnitude();

sphere1.position -= OverlapNormal * overlap_depth * 0.5f;
sphere2.Position += OverlapNormal * overlap_depth * 0.5f;

the same applies to sphere/plane collision, if you do a time-based collision detection (let''s call it a swept volume test). If sphere intersects plane, move it away from the plane so it is on the surface of the plane.

also, if you find (D * O) > 0.0f (''*'' is dot product for me), you may want to cut the collision test early, or you could have a build up of energy, of the spheres could get entangled or ''sticky'' (if you reflect velocities).

Everything is better with Metal.

Advertisement
I have come up with something

CP1 and CP2 - Position of Spheres at first contact
P1 and P2 - Positions of Spheres at end of timestep, where
they were intersecting
V1 and V2 - Velocity of spheres
t - time of first contact.
R1 and R2 - Radii


// Now by backtracking the positions by t the collision point
// can be found, but these two equations leave 3 unknowns.
// CP1, CP2 and t, therefore we need another eqn to solve them
CP1 = P1 - V1.t
CP2 = P2 - V2.t

// the sum of their radii is the same as the distance between
// the spheres
R1 + R2 = |CP1 - CP2|

// substituting ( | | = magnitude or length of the vector )

R1 + R2 = |(P1 - V1.t) - (P2 - V2.t)|
--------------------------------------

can this be solved? or am i just being dodgy!! :-)

EDIT -----------------------------------------------

Ok May have solved it:

R1 + R2 = |(P1 - V1.t) - (P2 - V2.t)|

R1 + R2 = |P1 - V1.t - P2 + V2.t|

R1 + R2 = |P1 - V1.t - P2 + V2.t|

R1 + R2 = |P1 - P2 - t(V1 - V2)|

0 = |P1 - P2 - t(V1 - V2)| - (R1 + R2)

|t(V1 - V2)| = |P1 - P2| - (R1 + R2)


t = |P1 - P2| - (R1 + R2)
------------------------
|V1 - V2|

Is that right? if so then now i can work out t, which would allow me to work out CP1 and CP2, giving me the EXACT point and time when the spheres first touch.


[edited by - aleks_1661 on January 14, 2004 8:24:36 AM]

Twitter: [twitter]CaffinePwrdAl[/twitter]

Website: (Closed for maintainance and god knows what else)

Proposed alternative solution:


Correct me if I''m wrong but it seems you could lineraly interpolate the distance between the centers of the spheres to determine point of contact. Example:

Scenario
Sphere A Radius = 2
Sphere B Radius = 3

Initial distance = 5.5 // Distance between centers
Initial Time = 0

At some time t, collision occurs at Distance = 5 (2 + 3)

Final Distance = 4.8 // Distance between centers
Final Time = 700 ms

It seems logical to assume collision occured at 500ms. Is this not true? Is the relationship not linear?






-----------
VenDrake

"My stupid jar is full. I can''t talk to you anymore."
-------------VenDrakeTo understand recursion, you must first understand recursion.
quote:Original post by aleks_1661
Ok I have a problem in the above equation,

-------------------
equivalent to a second order equation
a.t2 + b.t + c = 0

where

a = D2
b = 2.(D.O)
c = O2 - r2
--------------------

Now D and O are Vectors ( or a point and a vector). is D.O a dot product or cross product?


yeah, D . O is a dot product, as well as D * O (it''s the ''*'' overload operator for vectors).

D2 is (D * D). A dot product of a vector by itself, it''s also equal to the length squared of the vector''D''.

Everything is better with Metal.

quote:Original post by aleks_1661
// the sum of their radii is the same as the distance between
// the spheres
R1 + R2 = |CP1 - CP2|

// substituting ( | | = magnitude or length of the vector )

R1 + R2 = |(P1 - V1.t) - (P2 - V2.t)|
--------------------------------------

can this be solved? or am i just being dodgy!! :-)



this can be solved if you square the equation

(R1 + R2)2 = |CP1 - CP2|2

(R1 + R2)2 = (CP1 - CP2)2

which is the equation I use

(R1 + R2)2 = ((P1 - P2) + (V1 - V2).t)2

it''s exactly the same thing

Everything is better with Metal.

quote:Original post by aleks_1661
EDIT -----------------------------------------------

Ok May have solved it:

R1 + R2 = |(P1 - V1.t) - (P2 - V2.t)|

R1 + R2 = |P1 - V1.t - P2 + V2.t|

R1 + R2 = |P1 - V1.t - P2 + V2.t|

R1 + R2 = |P1 - P2 - t(V1 - V2)|

0 = |P1 - P2 - t(V1 - V2)| - (R1 + R2)

|t(V1 - V2)| = |P1 - P2| - (R1 + R2)


t = |P1 - P2| - (R1 + R2)
------------------------
|V1 - V2|



this is wrong.

0 = |P1 - P2 - t(V1 - V2)| - (R1 + R2)
=> |t(V1 - V2)| = |P1 - P2| - (R1 + R2)

you assume that |A + B| = |A| + |B|

which it isn''t. too bad, it would be simpler otherwise

Everything is better with Metal.

your right.

The linear interpolation should work. God knows why i hadn''t seen that one!!!

Ill try both, see where I end up.

also i should have realised the modulus idea was lame!

Forums make the internet a better place. And having a forum with clever people makes them an incredible resource.

Twitter: [twitter]CaffinePwrdAl[/twitter]

Website: (Closed for maintainance and god knows what else)

quote:Original post by VenDrake
Proposed alternative solution:


Correct me if I''m wrong but it seems you could lineraly interpolate the distance between the centers of the spheres to determine point of contact. Example:

Scenario
Sphere A Radius = 2
Sphere B Radius = 3

Initial distance = 5.5 // Distance between centers
Initial Time = 0

At some time t, collision occurs at Distance = 5 (2 + 3)

Final Distance = 4.8 // Distance between centers
Final Time = 700 ms

It seems logical to assume collision occured at 500ms. Is this not true? Is the relationship not linear?






-----------
VenDrake

"My stupid jar is full. I can''t talk to you anymore."


that would be fine if the spheres were moving exactly towards each other. But if they clip each other, like in a pool game, that won''t be sufficient.

if you need to get the points of contact, without all that malarkey, simply do

Vector N = (P2 - P1);
N.Normalise();

Pcoll1 = P1 + N * r1
Pcoll2 = P2 - N * r2

Everything is better with Metal.

This topic is closed to new replies.

Advertisement