Sign in to follow this  

Repositioning circles on collision

This topic is 2043 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

Hey, I'm trying to make an asteroids clone an I'm wandering how to reposition circles when they collide.
It would be easy to just do velocity = -velocity but the objects move fast so when the collide they get pretty far into each other so when they try to rebound it just gets stuck...

Here's the formula for what I did before (doesn't work very well):
diff = pos2 - pos1
if(pos1 < pos2){
pos1 = pos1 + ((diff - r)/2)
pos2 = pos2 - ((dif - r)/2)
}else if(pos2 > pos1){
pos1 = pos1 + ((diff + r)/2)
pos2 = pos2 - ((dif + r)/2)
}

pos1 is the position of one circle
pos2 is the position of another circle
diff is the difference between positions
r is the radius
it divides by 2 to space them equally.

When I try this in my project it doesn't work. Both the circles move with each other in a weird vibrating motion...
Any help will get +1 rep thanks! Edited by CryoGenesis

Share this post


Link to post
Share on other sites
Inverting velocity (preferably only along the normal component) works just fine if you first check whether they are actually moving towards each other.

Edit: also your code has "pos2<pos2" in the second if... Edited by japro

Share this post


Link to post
Share on other sites
Thanks but I wont be keeping the rebound as inverting the velocity.
I will be doing energy transference which can make a small object moving incredible fast, collide with a big circle (getting pretty far into the circle) and rebound to a really slow speed which will make the program keep thinking there is a collision.

Equation for the energy transference:
Velocity1 = (Velocity2 * Mass2)/Mass1;
where 1 means first circle (entity).
and 2 means the second circle (entity).

Share this post


Link to post
Share on other sites
Back to your original code:
[code]
diff = pos2 - pos2
if(pos1 < pos2){
pos1 = pos1 + ((diff - r)/2)
pos2 = pos2 - ((diff - r)/2)
}else if(pos2 > pos1){
pos1 = pos1 + ((diff + r)/2)
pos2 = pos2 - ((diff + r)/2)
}[/code]
Is that the actual code from the program or did you rewrite this in the browser? you calculate diff as pos2-pos2 which is always 0 then pos1<pos2 doesn't make sense for 2d vectors/positions to begin with. Is r the radius of a single circle? In that case the "penetration" is 2*r-diff and the position updates should read "pos1 += (2*r-diff)/2" etc. (never 2*r+diff tough, you are inverting the wrong sign in the second part of the if) Edited by japro

Share this post


Link to post
Share on other sites
Okay, it's easy to determine how far to move them back so they're just touching; if the radiuses of the two circles are r1 and r2, the centres should be r1+r2 apart. You can break the relative motion into two components; towards each other and at right angles. The component towards each other should be reversed and the other component can probably stay the same. If you know the component towards each other and how far they interpenetrated you could even estimate when they should have made contact, and calculate where they should go next.

Share this post


Link to post
Share on other sites
[quote name='japro' timestamp='1336220998' post='4937587']
Back to your original code:
[code]
diff = pos2 - pos2
if(pos1 < pos2){
pos1 = pos1 + ((diff - r)/2)
pos2 = pos2 - ((diff - r)/2)
}else if(pos2 > pos1){
pos1 = pos1 + ((diff + r)/2)
pos2 = pos2 - ((diff + r)/2)
}[/code]
Is that the actual code from the program or did you rewrite this in the browser? you calculate diff as pos2-pos2 which is always 0 then pos1<pos2 doesn't make sense for 2d vectors/positions to begin with. Is r the radius of a single circle? In that case the "penetration" is 2*r-diff and the position updates should read "pos1 += (2*r-diff)/2" etc. (never 2*r+diff tough, you are inverting the wrong sign in the second part of the if)
[/quote]

No the code is just written into the browser (badly).
The reason it does /2 is so the circles move an equal distance instead of just one circle moving and making the collision look a bit weird in the program.
At the moment both the radiuses are the same so I haven't put any support for different sizes.
I wrote the code into the browser because if it were actual code it would be a bit longer (for both x and y axis).

Heres the actual code at the moment:
[CODE]
int diffx = ent.x - x;
int diffy = ent.y - y;

int p1x = x,p1y = y;
int p2x = ent.x, p2y = ent.y;

if(x < ent.x){
int am = (diffx - circularRadius)/2;
p1x = x + am;
p2x = ent.x - am;
}else if(x > ent.x){
int am = (diffx + circularRadius)/2;
p1x = x + am;
p2x = ent.x - am;
}


if(y < ent.y){
int am = (diffy - circularRadius)/2;
p1y = y + am;
p2y = ent.y - am;
}else if(y > ent.y){
int am = (diffy + circularRadius)/2;
p1y = y + am;
p2y = ent.y - am;
}
x = p1x;
y = p1y;
ent.x = p2x;
ent.y = p2y;


rebound(ent);
[/CODE]

ent is the Entity that the circle is colliding with. Edited by CryoGenesis

Share this post


Link to post
Share on other sites
Hi

Maybe you should check for collision if there is move them back so that they are now on the bounds of the collision and then change there velocity that should stop them getting stuck inside each other.

oops i think i misread the question.

so move the centre of the colliding circle back along the direction of travel -x, -y, by the amount of distance between the two radius of both circles. then handle the colision Edited by thestien

Share this post


Link to post
Share on other sites

This topic is 2043 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this