Skip to main content
gamedev.net
🔒 Locked

Circle Collisions!?!??!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Started by thickinthehead 12 replies 900+ views
Original Post
thickinthehead
thickinthehead
Can anyone please tell me how to detect the angle at which two circles collide?!?!?!?!? Equations and any input is greatly appreciated!
NewDeal
NewDeal
Im on my way to bed, so ill make this short.

I suppose you know the center of both circles. Then you also know that collision occured at the middle of the line connecting the 2 centers. Finding the angle in the right-angled triangle made with the line centerX-collisionspot as the hypotenuse shouldnt be too hard (use the basic sin/cos relations).

Hope it helped


Edited by - newdeal on September 14, 2000 9:37:04 PM
ahw
ahw
The problem is that you are talking about CIRCLES here ... and circles, as far as I know, can''t it each other at any other angle than 0° ?
What you want is compare the movement vectors of each object represented by the circles, and calculate the angle between those vectors.
Not sure I am very clear here ... but basically I think you are asking the wrong question ... there is no ''angle'' when two circles collide AFAIK

youpla :-P
-----------------------------Sancte Isidore ora pro nobis !
NewDeal
NewDeal
Yeah, 2 circles can hit each other at other angles than 0. Imagine 1 circle just barely hitting the other. Like a hit that makes a ball spin ín pool (i dont know the english word for it).
NBGH
NBGH
Consider two circles at the point of impact. Both have a velocity vector in terms of the change in the x and the y coordinates of their position each frame (or per second etc). In order to work out the resultant change in these vectors, you must first establish the angle of the tangent that they share. In other words, this angle is the angle between the two circle centers relative to the x axis, plus 90 degress:

// center 1 = (x1, y1)
// center 2 = (x2, y2)
#define pi 3.1415926535
#define RadiansToDegress(theta) theta * (180 / pi)

TangentAngle /*(in radians)*/ =
tan( (y2 - y1) / (x2 - x1) ) + (pi / 2);

Once you have this angle, you can work on each circle independantly, pretending that each circle is bouncing off of a wall at the angle of the tangent, that you have just worked out.
This algorithm works well as long as you have a basic grasp of trig. If you are unsure, then email me at bigmannaytan@yahoo.com
and I will send you a diagram (BMP) and some code ''cos I''m nice like that.
Jumpster
Jumpster
The english word is called: "English" or Top-Spin, Side-Spin, Back-Spin etc. for the less savvy players.

Regards,
Jumpster

"Blood makes the grass grow! Kill! Kill! Kill!" - U.S. Marine Corps Chant
Regards,JumpsterSemper Fi
NewDeal
NewDeal
oh well, forget what ive posted. Im wrong hehe.
ahw
ahw
I think maybe thickinthehead could be more precise ...
is he trying to do a pool simulator ??
In this case I would advise to go on Gamasutra, there is an EXCELLENT serie of articles on collision and such, using the example of pool balls Spin effects included.

I think what I was trying to say is that if you only have two balls touching, there is no real way to tell anything about them. Now if you have data like the weights, the radiuses, the speed vector, the friction factors, that''s another, much more interesting story ...
-----------------------------Sancte Isidore ora pro nobis !
Jumpster
Jumpster
For a while there I thought I was walking right into an ambush. Thanks for taking it easy on me NewDeal

Jumpster

Semper Fi
Regards,JumpsterSemper Fi
nes8bit
nes8bit
!!!!!!!!!!!!!!!!!!!!!!

please...just please...that''s damn annoying...Sorry. I just had to say it!?!?!?!?!?!?!?!?!?!?!?!?!
?!!?!?!?!?

---------------------------
"communists eat little kids." -The Alchemist
ahw
ahw
simply add the balls movement vectors, factored by a bounce_coefficient.

A.xspeed = (A.xspeed*A.bounce) + (B.xspeed*B.bounce);
A.yspeed = (A.yspeed*A.bounce) + (B.yspeed*B.bounce);

yes, it's that easy; no it's not exact physics, but it works, as far as I know (or maybe I am going too fast ?)

youpla :-P


(ps: there is something phisically wrong here ... you gonna have to try it and tweak it)

Edited by - ahw on September 16, 2000 3:47:26 PM
-----------------------------Sancte Isidore ora pro nobis !
Khaos
Khaos
Try this:

for (int ball_a = 0; ball_a < NUM_BALLS; ball_a++)
{
for (int ball_b = ball_a+1; ball_b < NUM_BALLS; ball_b++)
{
if (ball_a == ball_b)
continue;

// compute the normal vector from a->b
float nabx = (balls[ball_b].varsF[INDEX_X] - balls[ball_a].varsF[INDEX_X] );
float naby = (balls[ball_b].varsF[INDEX_Y] - balls[ball_a].varsF[INDEX_Y] );
float length = sqrt(nabx*nabx + naby*naby);

// is there a collision?
if (length <= 2.0*(BALL_RADIUS*.75))
{
// the balls have made contact, compute response

// compute the response coordinate system axes
// normalize normal vector
nabx/=length;
naby/=length;

// compute the tangential vector perpendicular to normal, simply rotate vector 90
float tabx = -naby;
float taby = nabx;

// draw collision
DDraw_Lock_Primary_Surface();

// blue is normal
Draw_Clip_Line(balls[ball_a].varsF[INDEX_X]+0.5,
balls[ball_a].varsF[INDEX_Y]+0.5,
balls[ball_a].varsF[INDEX_X]+20*nabx+0.5,
balls[ball_a].varsF[INDEX_Y]+20*naby+0.5,
252, primary_buffer, primary_lpitch);

// yellow is tangential
Draw_Clip_Line(balls[ball_a].varsF[INDEX_X]+0.5,
balls[ball_a].varsF[INDEX_Y]+0.5,
balls[ball_a].varsF[INDEX_X]+20*tabx+0.5,
balls[ball_a].varsF[INDEX_Y]+20*taby+0.5,
251, primary_buffer, primary_lpitch);

DDraw_Unlock_Primary_Surface();

// tangential is also normalized since it''s just a rotated normal vector

// step 2: compute all the initial velocities
// notation ball: (a,b) initial: i, final: f, n: normal direction, t: tangential direction

float vait = DOT_PRODUCT(balls[ball_a].varsF[INDEX_XV],
balls[ball_a].varsF[INDEX_YV],
tabx, taby);

float vain = DOT_PRODUCT(balls[ball_a].varsF[INDEX_XV],
balls[ball_a].varsF[INDEX_YV],
nabx, naby);

float vbit = DOT_PRODUCT(balls[ball_b].varsF[INDEX_XV],
balls[ball_b].varsF[INDEX_YV],
tabx, taby);

float vbin = DOT_PRODUCT(balls[ball_b].varsF[INDEX_XV],
balls[ball_b].varsF[INDEX_YV],
nabx, naby);


// now we have all the initial velocities in terms of the n and t axes
// step 3: compute final velocities after collision, from book we have
// note: all this code can be optimized, but I want you to see what''s happening

float ma = balls[ball_a].varsF[INDEX_MASS];
float mb = balls[ball_b].varsF[INDEX_MASS];

float vafn = (mb*vbin*(cof_E+1) + vain*(ma - cof_E*mb)) / (ma + mb);
float vbfn = (ma*vain*(cof_E+1) - vbin*(ma - cof_E*mb)) / (ma + mb);

// now luckily the tangential components are the same before and after, so
float vaft = vait;
float vbft = vbit;

// and that''s that baby!
// the velocity vectors are:
// object a (vafn, vaft)
// object b (vbfn, vbft)

// the only problem is that we are in the wrong coordinate system! we need to
// translate back to the original x,y coordinate system, basically we need to
// compute the sum of the x components relative to the n,t axes and the sum of
// the y components relative to the n,t axis, since n,t may both have x,y
// components in the original x,y coordinate system

float xfa = vafn*nabx + vaft*tabx;
float yfa = vafn*naby + vaft*taby;

float xfb = vbfn*nabx + vbft*tabx;
float yfb = vbfn*naby + vbft*taby;

// store results
balls[ball_a].varsF[INDEX_XV] = xfa;
balls[ball_a].varsF[INDEX_YV] = yfa;

balls[ball_b].varsF[INDEX_XV] = xfb;
balls[ball_b].varsF[INDEX_YV] = yfb;

// update position
balls[ball_a].varsF[INDEX_X]+=balls[ball_a].varsF[INDEX_XV];
balls[ball_a].varsF[INDEX_Y]+=balls[ball_a].varsF[INDEX_YV];

balls[ball_b].varsF[INDEX_X]+=balls[ball_b].varsF[INDEX_XV];
balls[ball_b].varsF[INDEX_Y]+=balls[ball_b].varsF[INDEX_YV];

} // end if

} // end for ball2

} // end for ball1

} // end Collision_Response

Sorry if that was too long. I hope that helps. Let me know if it does or how you turn out.


"I Know Kung-Fu"
Khaos
Khaos
Let me know if that helps!

"I Know Kung-Fu"

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.