View Full Version : METAL: Circle collisions
I am programming a pool game in METAL basic and I have figured out this code to detect if 2 circles collide
if r1+r2 > sqr((x2-x1)^2+(y2-y1)^2) then
'Collision detected
end if
Now that I know they hit each other, how do I calculate the new velocitys of the circles? Can you tell me the equation if their old velocitys were vx1,vy1,vx2,vy2.
Thanks. Also please don't make it in C code, just use BASIC code or psuedocode.
FCCovett
2002.12.24, 12:50 PM
there is a good article on Gamasutra about collisions for a pool game. It's really worth a read.
codemattic
2002.12.24, 05:22 PM
you can make this run a little faster if you want. Square root operations are very slow. So you could use:
if r1^2+r2^2 > (x2-x1)^2+(y2-y1)^2 then
that way you avoid the sqr() and you can precompute r1^2 and r2^2 if you want.
A quick way to handle the collision is to swap velocities. After the collision r1 is moving in the direction that r2 was and visa versa. This isnt physically correct of course - but its very easy to do, and usually looks ok.
But - if you want to be accurate...
Finding out that two spheres currently intersect isnt enough - you need the find the time and point of contact. If the previous frame they didnt overlap but this frame they do overlap - that means at some time in between frames they first came in contact - and thats the time you want to look at.
If you wish to be more accurate you need to learn some vector math - especially what the dot product is and what it is used for. Then read the article that FCCovett talked about here (free registration required):
<http://www.gamasutra.com/features/20020118/vandenhuevel_pfv.htm>
It explains everything in detail, has well documented Java code examples (sorry no METAL, but its pretty easy to follow). I use these algorithms for colliding spheres and circles and it works very well. But learn about vectors and dot product first - or you will be lost.
good luck, hth,
Codemattic
Im lost, I am asking alot here but can somebody write the code, eather in METAL or BASIC or pseudocode or whatever. I am only 15 so I don't know what a dot product is or stuff like that
David
2002.12.24, 07:53 PM
You will continue to not know what they are until you put some effort into learning it :) Don't use age as an excuse.
kelvin
2002.12.24, 07:55 PM
r1^2+r2^2 > (x2-x1)^2+(y2-y1)^2 is wrong.
(r1 + r2)^2 = r1^2 + 2*r1*r2 + r2^2
this is basic algebra man.
shame on you.
Holmes
2002.12.24, 08:17 PM
Yes, he is wrong.
(r1+r2)^2 = r1^2+r1*r2+r2^2 and not r1^2+r2^2, but its not exactly a reason for shame.
The basic idea is right. Square roots take a long time to compute and are pointless if you're just checking relationships like >, <, or = since you don't need to know the ACTUAL distances anyway, just how they relate to one another.
And swapping velocities is in perfect accordance with physics assuming that
1. The objects are of equal mass
2. Its an elastic collision (no crunching or energy lost due to heat or whatever)
A good way to configure the velocities if the objects are not of equal mass then remember conservation of momentum. The momentum of the system (the sum of each objects mass * velocity) will be the same both before and after the collision (again, assuming an ellastic collision). You can derrive a system from there.
This is way over my head, I will learn it eventualy, but I need some time. Can somebody please help me here.
David
2002.12.24, 09:33 PM
Didn't someone post an open-source physics engine thingy somewhere that included this?
They posted the executable, not source.
I just re-read the tutorial and I am still confused. Not understanding Java code doesn't help much eather.
I may just have to figure this out on my own :(
codemattic
2002.12.25, 12:30 AM
Originally posted by kelvin
this is basic algebra man.
shame on you.
I am so friggin *busted* :oops: - thanks for spotting my error.
-Codemattic
FCCovett
2002.12.25, 03:16 AM
Jake, it really doesn't get any easier than that article, and I don't have the code in BASIC.
Basically, this is a problem that I just got to study in the second year of the engineering school. "Afraid you will be; very afraid." :)
codemattic
2002.12.25, 06:03 AM
Originally posted by Jake
I am only 15 so I don't know what a dot product is or stuff like that
Im not sure what one has to do with the other. It is all within your abilities - its mostly arithmetic. Everything looks strange and unlearnable when you first look at it. Besides I would imagine being 15 is a benefit to learning new ideas.
Start with the code you have. When balls collide have them react by switching the velocities. Build the rest of the game using that. There still are lots of things for you to figure out. Dont give up just because one article looks intimidating. When you get the rest working - maybe you will go back and write better collision code - or maybe it will be fun as is.
There are sims that try and be as accurate as possible. Taking english (spin) into account is going to be very tricky also. But then there are arcade type games - that arent such in depth simulation. (like flying games - some model the physics of flying and are 'faithful' - while some are arcade-like and have very simple physics, but you can get flying and blowing things up quickly!) So make what you can.
Maybe you can play on different shaped tables instead of just the standard one? What would a 3d pool 'table' play like - that is if instead of playing on a surface you played in a volume (a cube or a box) - like thats how you can play pool in zero-g.
cheers,
Codemattic
Originally posted by codemattic
Maybe you can play on different shaped tables instead of just the standard one? What would a 3d pool 'table' play like - that is if instead of playing on a surface you played in a volume (a cube or a box) - like thats how you can play pool in zero-g.
cheers,
Codemattic
I was thinking about that 3D pool, but was waiting for METAL 2.0 to come out with open GL.
I will just switch velocties for now, and then work from there.
Joseph Duchesne
2002.12.28, 06:21 PM
Swap velocities but do something like this:
if sprite collides(ball1,ball2) then swap b1xs*.9,b2xs : swap b1ys*.9,b2ys
so you loose some speed.
also maybe you should have a max speed you can hit the ball with. If you have 2 screens like I do you can drag the mouse way to far away and it wizzes around until at least 1 ball go's in the hole.
kemalyun
2002.12.31, 10:36 AM
Here's a simple code:
Assuming the vx1,vy1 and vx2,vy2 are the horizontal and vertical speeds of the objects,
if theycollide then
swap vx1,vx2
swap vy1,vy2
endif
Now don't forget that the balls should loose speed all the time (or they will move til the end of days!). Use something like
vx1=vx1*0.9
vy1=vy1*0.9
in your mainloop. Experiment with the value (0.9) to get it looking realistic.
By the way, you got the code of FLOWMOTION, check that, there the blocks also swap speed, but they don't get slower.
Hope that helped.
That works great for boxes or rectangles, but for a pool game those physics don't cut it. Do you know what I mean kemal?
skyhawk
2002.12.31, 06:45 PM
for elastic collisions
if(Hit(b1,b2)) //if hit, bounce them
{
double n[2]={b1->X-b2->X,b1->Y-b2->Y};
double v1[2]={b1->XV,b1->YV};
double v2[2]={b2->XV,b2->YV};
double v3[2];
double v4[2];
double temp[2];
double m=magnitude(n);
double a1,a2;
double optp;
n[0]/=m; //normalize n
n[1]/=m;
a1=dot(v1,n,2);
a2=dot(v2,n,2);
optp=(2.0*(a1-a2))/(2*circmass);
temp[0]=optp*circmass*n[0];temp[1]=optp*circmass*n[1];
v3[0]=v1[0]-temp[0];v3[1]=v1[1]-temp[1];
v4[0]=v2[0]+temp[0];v4[1]=v2[1]+temp[1];
b1->XV=v3[0];b1->YV=v3[1];
b2->XV=v4[0];b2->YV=v4[1];
}
yes I am aware there are a lot of unneccesary variable defining in there.
I don't program in C, but will that code work for a pool game (are the physics correct, or is that just another way to get it to kinda work)
kemalyun
2003.01.01, 08:44 AM
You're right, my example works only for square objects.
When the objects are round, the angle has to be considered.
What I can think of, without knowing the correct physics, is:
Draw a line between the two centers of the balls. This is the angle which has to be added to the angle of the movement of both balls I think.
In order to calculate this, you have to get away from the simple x-speed and y-speed rule and use a total speed- and an angle-parameter. Then you can switch the angles and speeds when the balls collide, detect the hit-angle (from the centers of the balls) and add that to both angles. That should work fine.
But, other idea: I think there are a lot of standard-pool-games outside. Why not do one with square-balls? "Squool"? Maybe I'll adapt Flowmotion to that, should be very easy indeed.
I see what you mean by the angel/velocity oposed to x-y velocitys, but I have already came up with a solution to the problem. Here is what I have with ball i and j colliding.
balls(i,1) is the x location
balls(i,2) is the y location
balls(i,3) is the x speed
balls(i,4) is the y speed
v(i,whatever) = the new speed of the ball (added at the end of the loop)
This code works actualy pretty good, the pool game is realistic and you can cut balls and give them specific angles, just like in real life.
ix = balls(i,1)
jx = balls(j,1)
iy = balls(i,2)
jy = balls(j,2)
v(i,3) = v(i,3) + ((ix-jx)/16)*sqr(balls(j,3)^2+balls(j,4)^2)+.05+((iy-jy)/16)*balls(i,3)
v(i,4) = v(i,4) + ((iy-jy)/16)*sqr(balls(j,3)^2+balls(j,4)^2)+.05+((ix-jx)/16)*balls(i,4)
v(j,3) = v(j,3) + ((jx-ix)/16)*sqr(balls(i,3)^2+balls(i,4)^2)+.05+((jy-iy)/16)*balls(j,3)
v(j,4) = v(j,4) + ((jy-iy)/16)*sqr(balls(i,3)^2+balls(i,4)^2)+.05+((jx-ix)/16)*balls(j,4)
kemalyun
2003.01.01, 05:55 PM
That's good!
I'm currently making the FLOWMOTION game with music, sound and gfx assets. It's really cool.
What will you do with the Pool-game when finished?
I don't know what I am going to do with it when Im finished. I might add some trick shots and give it away as freeware on my site.
Are you going to make your new game shareware kemal?
vBulletin® v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.