This topic is now archived and is closed to further replies.

circle - circle collision response (2D)

This topic is 5042 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi, i have a basic simulation setup whereby, in accordance with newton''s laws, the only way to affect an object in motion is to apply a force to it (gotta do it like that im afraid) i have detected two circle''s colliding, but am having trouble with the response.. after looking around i learnt how to directly affect the velocity of the two, which works, but unfortunatly i am restricted to keeping the simulation accurate to newton''s laws, therefore i need to calculate a force to apply to each circle, so that the formula f = ma (a = f/m) can be caclulated. Thanks in advance, Hybrid

Share this post

Link to post
Share on other sites
you need to do a bit more physics than when doing a simple reflection algo.

to be accurate, you need the relative velocity at the point of contact, the inertia of the spheres (how hard is it to spin them), obviously the masses, and then you can apply a proper collision impulse at the point of contact for the spheres. wothout friction, the impact will never produce any spinning, as the impact force will be directly in line with the contact normal (their cross product is 0).

look at chris hecker''s physics page

and also, you can see another implementation of his stuff here

it''s based on boxes, but for spheres, it''s exactly the same thing, as long as you supply the wo penetration point on the two spheres.

Share this post

Link to post
Share on other sites
i wasnt planning on implementing spinning into it.. :\

basically, one of the circles is moved around manually with the mouse, and is totally immovable through collision with the other circle, so just looking for simple collision reaction based on the angle of contact and the closing velocity (ve2-vel1) ?

ps are u following me around all day trying to solve all my probs...? seem to remember u helping me before :D

Share this post

Link to post
Share on other sites
Is the goal to transfer inertia/energy from one circle to the other, or is the goal to make the circles not intersect?

If the goal is to make the circles not intersect on the next step, you calculate the depth of penetration, and then calculate the force that will accelerate the object such that it moves exactly half the penetration depth in exactly one time step (this is easier if the time step is always the same). Apply the acceleration calculated for each object, as an impulse (i e, as a force for only one step) on each of the objects.

If the goal is to do a "realistic" exchange of forces and inertia, then it''s not certain that the objects will separate, and they''ll collide the next step too, and you''ll have to be prepared for this (and not make it magically gain energy that step). Easiest is to treat one of the objects as stationary, by subtracting its velocity from the other object. Then, calculate bouncing/interaction between the other object and that "stationary" object. Then add the first object movement back in to both objects.

Share this post

Link to post
Share on other sites
could you elaborate a bit on the exchange of forces?
say I have 2 spheres with position, direction and velocity and want them to respond correctly when they collide. Leaving the velocity aside, I would simply mirror each direction, but I have no idea how to include it in this calculation.

I dont understand your ''make one object stationary'' approach. The stat. object will then move in the direction of center1-center2, when I''m not mistaken...

Share this post

Link to post
Share on other sites
circles, not spheres.. and mirrorin directions..? ouch

1 is unyielding because user controls that circle, other circle just bounces off it

..anyway think i got it sorted now, cheers oliiii

Share this post

Link to post
Share on other sites
Here''s is code I wrote in darkbasic pro which will do the basics of what you want I think. It should be easy enough to understand and put into C++ or whatever.

x1# = 300
y1# = 200
r1# = 50
r2# = 30

oldx2# = x2#
oldy2# = y2#

ink rgb(255,255,255),0
circle x1#,y1#,r1#
circle x2#,y2#,r2#

rem only calculate point of intersection if circles are intersecting
if (x1#-x2#)^2 + (y1#-y2#)^2 <= (r1#+r2#)^2
x# = newxvalue(x1#,angle#,r1#)
y# = newzvalue(y1#,angle#,r1#)
hit = 1
a# = wrapvalue(angle#+180)

rem show point of intersection
ink rgb(255,0,0),0
circle x#, y#,2

if hit = 1
`v# = sqrt((oldx2#-x2#)^2 + (oldy2#-y2#)^2)
v# = 5
moving = 1
hit = 0

if moving = 1
if x1#+r1# > screen width()

if x1# < r1#

if y1# < r1#

if y1#+r1# > screen height()

a# = atanfull(vx#,vy#)

x1# = newxvalue(x1#, a#, v#)
y1# = newzvalue(y1#, a#, v#)

set cursor 0,0
print mousemovex()
print mousemovey()
print a#
print vx#
print vy#


Share this post

Link to post
Share on other sites
cheers for the help so far people

so far, i ''think'' i''v perfected my circle collision detection.. it evaluates where circles will be on the next frame and computes if they''l intersect, which iv tested and seems to work

anyway, for my collision response.. iv got this:

// normalised directional vector from circle1-> circle2
VECTOR3D n = (m_Position - st.getPosition()).normalise();

// angle of contact
double angle = (m_Velocity * dt).dotProduct(n) * PIUNDER180;

// remove sign
if(angle < 0)
angle = -angle;

// massFactor is calcualted using the collision angle and the 2 masses
double massFactor = (m_Mass * angle) / (m_Mass + st.getMass());
n.setLength((m_Velocity.getLength()*dt) * massFactor);

// force acting upon the movable circle
return n;

.... this function seems to kind of work; it computes the correct angle and value for n as far as i can see, its just this stupid mass factor crap, it seems to balls it up, although i understand why its necessary.

note: im looking to apply a FORCE to the circle, not directly change its velcoity

thanks in advance

Share this post

Link to post
Share on other sites